我正在尝试从装饰器中获取局部变量。一个例子:
def needs_privilege(privilege, project=None):
"""Check whether the logged-in user is authorised based on the
given privilege
@type privilege: Privilege object, id, or str
@param privilege: The requested privilege"""
def validate(func, self, *args, **kwargs):
"""Validator of needs_privillige"""
try: check(self.user, privilege, project)
except AccessDenied:
return abort(status_code=401)
else:
return func(self, *args, **kwargs)
return decorator(validate)
装饰一个功能后,像这样:
@needs_privilege("some_privilege")
def some_function():
pass
我想从some_function中检索'privilige'变量(validate()使用)。搜索了一个多小时后,我感觉很迷茫。这可能吗?
修改: 让我更彻底地描述我的问题:我可以在没有执行some_function的情况下获得字符串“some_prvilege”吗?类似的东西:
a = getattr(module, 'somefunction')
print a.decorator_arguments
?谢谢你帮助我到目前为止!
答案 0 :(得分:3)
您的装饰器基本上检查用户是否具有执行给定功能的权限,我实际上并不理解为什么要将权限检索(附加)到正在包装的函数,但是您可以在不添加的情况下执行此操作你所有职能的另一个论点。
def needs_privilege(privilege, project=None):
"""Check whether the logged-in user is authorised based on the
given privilege
@type privilege: Privilege object, id, or str
@param privilege: The requested privilege"""
def validate(func, self, *args, **kwargs):
"""Validator of needs_privillige"""
try: check(self.user, privilege, project)
except AccessDenied:
return abort(status_code=401)
else:
return func(self, *args, **kwargs)
validate.privelege = privelege
return decorator(validate)
你的装饰师应该是这样的:
def needs_privilege(privilege, project=None):
def validate(func):
def new_func(self, *args, **kwargs):
try:
check(self.user, privilege, project)
except AccessDenied:
return abort(status_code=401)
else:
return func(self, *args, **kwargs)
new_func.privilege = privilege
return new_func
return validate
答案 1 :(得分:2)
您可以将其作为参数传递:
def needs_privilege(privilege, project=None):
"""Check whether the logged-in user is authorised based on the
given privilege
@type privilege: Privilege object, id, or str
@param privilege: The requested privilege"""
def validate(func, self, *args, **kwargs):
"""Validator of needs_privillige"""
try: check(self.user, privilege, project)
except AccessDenied:
return abort(status_code=401)
else:
return func(self, privilege, *args, **kwargs)
return decorator(validate)
@needs_privilege("some_privilege")
def some_function(privilege):
pass
答案 2 :(得分:1)
如果您不需要decorator
模块,问题就会简单得多。
如果你不是严格需要decorator
模块,你可以像这样编写装饰器:
def needs_privilege(privilege, project=None):
def validate(func):
def _validate(self, *args, **kwargs):
return func(self, *args, **kwargs)
_validate.decorator_args=(privilege,project)
return _validate
return validate
@needs_privilege("some_privilege")
def some_function(self):
pass
a = some_function
print(a.decorator_args)
# ('some_privilege', None)
答案 3 :(得分:0)
函数也是可以具有属性的对象。您可以在装饰器中设置属性。这是一个例子:
class TestClass(object):
def needs_privilege(privilege, project=None):
def wrapper(func):
def validate(self, *args, **kwargs):
"""Validator of needs_privillige"""
print 'validator check for %s' % privilege
return func(*args, **kwargs)
validate.privilege = privilege
return validate
return wrapper
@needs_privilege("foo")
def bar():
print "called"
>>> test.TestClass().bar()
validator check for foo
called
>>> test.TestClass.bar.privilege
'foo'
>>> test.TestClass().bar.privilege
'foo'