我有这段代码:
def check_karma(needed_karma, user_karma):
# check karma or exit
return True
def hello_world():
user_karma = 50
check_karma(20, user_karma)
print "Hello World"
我可以在这里使用装饰器吗?,像这样:
...
@check_karma(20, user_karma)
def hello_world():
user_karma = 50
print "Hello World"
我不知道是否可以访问函数内部的数据,因为我在测试脚本中成功编写了@check_karma(20)。
答案 0 :(得分:0)
是的,在这个实例中可以使用一个装饰器(它实际上可能是有益的),但是,它并不像定义一个函数那么简单。在这种情况下,您想要做的是定义所谓的仿函数。 仿函数是一个可以作为函数运行的类。
例如,假设你有班级Apple
。您可以通过执行以下操作来实例化此类的对象:
apple = Apple(color='red')
现在,如果这是仿函数,您可以使用apple
对象更进一步,就好像它是一个函数一样,通过apple()
调用它。这可以用来创建你想要制作的装饰器。您将在装饰器的定义中初始化check_karma
类,如下所示:
@check_karma(needed_karma)
def hello_world():
...
这是因为装饰者必须是函数才能返回另一个函数。上面的代码片段基本上是这样做的:
def hello_world():
...
hello_world = check_karma(needed_karma)(hello_world)
然后每次调用hello_world时,我们都会调用check_karma
仿函数返回的函数。 user_karma
可能应该从其他地方请求。
以下是如何在代码中应用此功能的示例:
user_karma = 50 # pretend this is where you store `user_karma`.
class KarmaRestrictor:
def __init__(self, needed_karma):
self.needed_karma = needed_karma
def __call__(self, restricted_func):
# This is the actual decoration routine. This `__call__` descriptor
# is what makes this class a **functor**.
def _restricted_func(*args, **kwargs):
if self.get_user_karma() >= self.needed_karma:
return restricted_func(*args, **kwargs)
else:
# TODO: Maybe have a failure routine?
pass
return _restricted_func
def get_user_karma(self):
return user_karma # wherever you store this.
check_karma = KarmaRestrictor # give this decorator an alias.
@check_karma(20)
def hello_world():
print 'Hello World'