【问题标题】:Unable to get a decorator to take a parameter [duplicate]无法让装饰器获取参数[重复]
【发布时间】:2021-03-21 03:12:09
【问题描述】:

我正在尝试创建一个可以使用或不使用参数的装饰器。到目前为止我有这个:

def logged_in(func=None, *, permissions=None):
    if func is None:
        return partial(logged_in, permissions=None)

    @wraps(func)
    def wrapper(*args, **kwargs) -> Callable:
        nonlocal permissions
        if not g.get('user'):
            response.unauthorized()
        if permissions:
            if type(permissions) == str:
                permissions = [permissions]
            if not g.user.admin and not bool(
                set(g.user.permissions) & set(permissions)
            ):
                response.forbidden()
        return func(*args, **kwargs)

    return wrapper

我称之为

@logged_in(permissions=['asdf'])
def my_method():

但是,我在if permissions: 处不断收到一个错误,即未设置权限。我正在使用a guide,尽管我在很多地方都看到过相同风格的代码。

【问题讨论】:

  • 您的函数wrapper 包含一个赋值permissions = ...,因此permissions 被解释为一个局部变量;要么你需要在wrapper的顶部写nonlocal permissions,要么在外部函数中重新赋值,要么重新赋值给不同的变量。

标签: python python-decorators


【解决方案1】:

permissions 在外部范围 (logged_in) 中定义并分配给内部范围 (wrapper)。在 Python 中,我们必须将这种情况声明为nonlocal

def wrapper(*args, **kwargs) -> Callable:
    nonlocal permissions
    ...

【讨论】:

  • 这是正确的做法吗?我发现的教程都没有这样做,所以如果我的代码错误,或者我应该使用不同的解决方案,我会感到困惑。
  • nonlocal 绝对是惯用的 Python。 “奇怪”的事情可能是您重新分配给permissions,而基本教程可能没有这样做
  • 对不起,我不明白你在这里重新分配的意思。我把它作为一个参数,但就是这样?我正在使用github.com/dabeaz/python-cookbook/blob/master/src/9/…
  • 在函数的后面,你做permissions = [permissions],这就是为什么你需要nonlocal。如果你不给参数赋值,那么没有也可以。
  • 啊,我明白你的意思了。但在此之前它失败了。事实上,我只是添加了非本地的,权限总是无,即使我尝试@logged_in(permissions=['asdf'])
猜你喜欢
  • 2023-03-26
  • 2014-10-14
  • 2013-07-19
  • 2019-06-10
  • 1970-01-01
  • 2018-01-21
  • 2011-10-04
  • 2021-09-28
相关资源
最近更新 更多