2013-04-17 122 views
0

我有一些方法具有屬性(使用.Net術語)。就像是。裝飾具有屬性的自定義屬性的方法

#Example Usage 
@RequireLoggedIn 
def SomeAuthorisedFunction(): 
    # ... 

該屬性被定義爲

def RequireLoggedIn(func): 
    func.AuthenticationRequired = True 
    return func 

然後我可以檢查是否這已被使用hasattr(view_func, 'AuthenticationRequired')設置。我想要做的就是這樣的事情...

@RequireRole('Administrator') 
def SomeAuthorisedFunction(): 
    # ... 

我試圖定義一個像這樣的屬性:

def RequireRole(func, Role): 
    func.RequiresRole = Role 
    return func 

@RequireRole('Administrator')導致missing positional argument "Role"@RequireRole(Role='Administrator')結果missing positional argument "func"

如何指定屬性的屬性?

+0

http:// stackoverflow。com/questions/5929107/python-decorators-with-parameters – ndpu

回答

3

你需要創建一個嵌套功能;該RequireRole函數返回的實際裝飾功能:

def RequireRole(Role): 
    def decorator(func): 
     func.RequiresRole = Role 
     return func 
    return decorator 

@expression語法無非是語法糖越多,以下設置:

@decorator 
def foo(): pass 

被翻譯成:

def foo(): pass 
foo = decorator(foo) 

代替。但decorator部分可以本身也是一個表達式;這就是你如何使用它。所以,當你使用@RequireRole('Administrator')作爲裝飾,你真正做到這一點:

def SomeAuthorisedFunction(): 
    # ... 
SomeAuthorisedFunction = RequireRole('Administrator')(SomeAuthorisedFunction) 

注意函數調用有!這就是我的RequireRole()版本返回嵌套函數的原因。這是當您應用它時會發生的情況:

  1. def SomeAuthorizedFunction(): functionbody被執行。
  2. RequireRole('Administrator') is executed. It returns a scoped decorator()`函數。
  3. 此返回的函數被調用,並從步驟1
  4. SomeAuthorizedFunction函數傳遞作用域decorator()函數將.RequiresRole屬性的功能,與在步驟2中被返回的函數傳遞到RequireRole作用域Role值。
  5. Python將步驟4的返回值分配給名稱SomeAuthorizedFunction
+0

感謝您的快速和詳細的回覆 – Basic

1

您的RequireRole函數必須返回裝飾器函數。這可以很容易地通過 嵌套函數來完成,像這樣:

>>> def RequireRole(role): 
... def RequireRole(func): 
...  func.RequiresRole = role 
...  return func 
... return RequireRole 
... 
>>> @RequireRole('Administrator') 
... def SomeAuthorisedFunction(): 
... pass 
... 
>>> print SomeAuthorisedFunction.RequiresRole 
Administrator 
>>> 
+0

感謝您的快速響應 – Basic