python装饰程序获取函数变量

python装饰程序获取函数变量,python,python-decorators,Python,Python Decorators,我有以下代码: 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 hel

我有以下代码:

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)。

是的,在这个实例中可以使用装饰器(实际上可能是有益的),但是,这并不像定义函数那么简单。在本例中,您要做的是定义称为函子的内容。函子是一个函数类

例如,假设您有一个类
Apple
。您可以通过执行以下操作来实例化此类的对象:

apple=apple(color='red')

现在,如果这是一个函子,您可以进一步使用
apple
对象,就像它是一个函数一样,使用
apple()
调用它。这可以用来创建您试图制作的装饰器。您将在装饰者的定义中初始化
检查\u karma
类,如下所示:

@check_karma(needed_karma)
def hello_world():
    ...
这是因为装饰器必须是返回另一个函数的函数。上面的代码片段基本上是这样做的:

def hello_world():
    ...
hello_world = check_karma(needed_karma)(hello_world)
然后每次我们调用hello\u world时,我们都在调用由
check\u karma
functor返回的函数<代码>用户_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'

用参数制作装饰器并不是那么简单。。。否,装饰程序无法访问局部变量。你可以把
user\u karma
作为
hello\u world()
的一个参数,否则你想做的是不可能的。
check\u karam
看起来就像我经常使用的
assert
一样