【问题标题】:Syntax of call of a decorator function in pythonpython中装饰器函数的调用语法
【发布时间】:2020-07-19 09:51:04
【问题描述】:

这是来自严重 Python 中的代码 sn-p,我在理解调用语法时遇到了问题。 check_user_is_not 是一个装饰器工厂,它返回一个装饰器。其余的语法也很简单。工厂定义如下。

def check_user_is_not(username):
    def user_check_decorator(f):
        def wrapper(*args, **kwargs):
            if kwargs.get('username') == username:
                raise Exception("This user is not allowed to get food")
            return f(*args, **kwargs)
        return wrapper
    return user_check_decorator

问题出在通话中。

class Store(object):
    def get_food(self, username, food):
        return self.storage.get(food)

Store.get_food = check_user_is_not("user123")(Store.get_food)   # Statement 1
Store.get_food = check_user_is_not("admin")(Store.get_food)     # Statement 2

语句 1 和语句 2 导致我的理解出现问题。 check_user_is_not("user123") 是什么?如果这是一个返回的函数,然后我们用另一个函数 Store.get_food 调用该函数,那么语法应该是 Store.get_food = check_user_is_not("user123")( (Store.get_food) ) # not sure if valid

我已经添加了额外的括号来将其视为调用。这个说法应该怎么理解?

我检查了其他装饰器问题,例如here,确实找到了与print_hi = repeat(num_times=4)(print_hi) 类似的代码。

这两个陈述是否有效且相同?

Store.get_food = check_user_is_not("user123")( (Store.get_food) ) # not sure if valid`
#vs
Store.get_food = check_user_is_not("user123")(Store.get_food)

这种类型的电话有什么具体的名字吗?

【问题讨论】:

  • 我不明白您为什么认为需要额外的括号。 check_user_is_not(<whatever>) 返回一个函数,你调用那个函数,check_user_is_not(<whatever>)(<something else>)... 这个没有名字,这只是一个普通的函数调用,和其他函数一样
  • 所以,check_user_is_not("user123")( (Store.get_food) ) 是有效的,但是分组括号不是必须的,可以是check_user_is_not("user123")( Store.get_food )
  • 谢谢,所以这是一个通用的函数调用。实际上括号已经在那里了。

标签: python-3.x decorator


【解决方案1】:

如果我们把它写成这样是否更有意义:

decorate = check_user_is_not("user123")
Store.get_food = decorate(Store.get_food)

decorate 是一个函数(在本例中为 user_check_decorator),然后我们调用它来获取另一个函数(在本例中为 wrapper)。 wrapper 装饰Store.get_food.

的确如此:

Store.get_food = check_user_is_not("user123")( (Store.get_food) )
Store.get_food = check_user_is_not("user123")(Store.get_food)

是相同的(并且有效),但可能不是您认为的原因。和下面的思路是一样的:

a = (1)
b = 1
assert a == b # a and b both equal 1

【讨论】:

  • 谢谢,Store.get_food = decorate(Store.get_food) 行更清楚了。猜猜这本书的作者(朱利安)想要更简洁。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-11
  • 2020-03-19
  • 2011-03-23
  • 2017-01-15
  • 2017-08-01
  • 2023-02-08
  • 2018-03-07
相关资源
最近更新 更多