获取函数的局部变量

3 投票
4 回答
562 浏览
提问于 2025-04-16 05:38

我想从一个装饰器中获取一个局部变量。举个例子:

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

?谢谢你们到目前为止的帮助!

4 个回答

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

撰写回答