有没有办法将变量传递给装饰器?

时间:2011-08-20 21:18:32

标签: python django

我有基于OpenID提供程序的登录系统,我想创建像@login_required这样的装饰器。但我有一个问题 - 我需要检查每个对象的权限。我将id传递给我的视图,所以我想知道有没有办法将它传递给装饰器,或者这是不可能的,我需要在我的视图中检查用户权限。

2 个答案:

答案 0 :(得分:3)

def outer(var1, var2):
    def inner(func)
        func.foo = var1
        func.bar = var2
        return func
    return inner

@outer(myvar1, myvar2)
def myfunc():
    # whatever
    pass

虽然你不能直接将变量传递给装饰你的函数的函数,你可以创建另一个函数outer),当被调用时,返回装饰函数inner)。您传递了outer个函数变量,它们可用于inner函数。这被称为闭包。

答案 1 :(得分:3)

根据您需要使用id执行的操作,您可能需要两个级别的包装,您可以在调用方法之前将print(permission_id)替换为您需要执行的操作:

def login_required(permission_id):
    def decorator(func):
        def method(self, *args, **kw):
            print(permission_id)
            return func(self, *args, **kw)
        return method
    return decorator

class foo(object):

    @login_required('foo')
    def bar(self):
        print('bar')

foo = foo()
print('instantiated')
foo.bar()

输出:

instantiated
foo
bar