我有一些具有属性的方法(使用.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 :(得分: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)
注意那里的 double 函数调用!这就是我的RequireRole()
版本返回嵌套函数的原因。这是你申请时会发生的事情:
def SomeAuthorizedFunction(): functionbody
已执行。RequireRole('Administrator') is executed. It returns a scoped
decorator()`function。SomeAuthorizedFunction
函数中传递。decorator()
函数将.RequiresRole
属性添加到函数中,并在步骤2中将作用域Role
传递给RequireRole
。函数将返回。SomeAuthorizedFunction
。答案 1 :(得分:1)
您的RequireRole
函数必须返回装饰器函数。这很容易
通过嵌套函数完成,如下所示:
>>> def RequireRole(role):
... def RequireRole(func):
... func.RequiresRole = role
... return func
... return RequireRole
...
>>> @RequireRole('Administrator')
... def SomeAuthorisedFunction():
... pass
...
>>> print SomeAuthorisedFunction.RequiresRole
Administrator
>>>