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

1 投票
2 回答
1846 浏览
提问于 2025-04-17 00:01

我有一个登录系统,是基于OpenID提供的服务。我想创建一个装饰器,类似于@login_required。但是我遇到了一个问题——我需要针对每个对象检查权限。我在视图中传递了对象的ID,所以我想知道有没有办法把这个ID传递给装饰器,或者说这不可能,我必须在视图中检查用户的权限。

2 个回答

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函数里使用。这种情况被称为闭包。

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

撰写回答