【问题标题】:What's going to happen in the python decorator that defines one more function?在定义另一个函数的 python 装饰器中会发生什么?
【发布时间】:2018-08-13 12:45:13
【问题描述】:

今天在学习装饰器的时候遇到一个问题,看下面两段代码 代码1:

def log(func):
    def wrapper(*args,**kw):
        print('call %s():' % func.__name__)
        return func(*args,**kw)
return wrapper

@log
def now():
    print('2018-8-28')

now()

代码2:

def log(func):
    print('call %s():' % func.__name__)
    return func

@log
def now():
    print('2018-8-28')

now()
print(type(now()))

为什么第一个代码定义了多个包装函数?两个代码的输出是一样的。

在代码2中,我对now函数使用type方法查看它的类型,结果类型为None

【问题讨论】:

  • 在您的问题中将代码摘录作为文本发布比屏幕截图链接更有用。
  • 第一个定义了一个装饰器和一个包装器。第二个根本没有定义包装器。输出只是相同的,因为您中间什么都不做。运行两次,您应该会看到不同。
  • 感谢上面的回答,我会仔细看看你的回答,应该不会有很多问题

标签: python python-3.x decorator


【解决方案1】:

在函数定义之前使用@log(或其他一些装饰器)将调用装饰器函数(在本例中为log),并将装饰器函数作为参数,并替换装饰器函数使用装饰器函数返回的函数,即类似于在函数初始声明后做now = log(now)

因此,“short”版本将在函数被修饰时打印一次“call”行,然后返回函数本身。另一方面,“长”版本每次调用函数时都会打印“调用”行,方法是返回一个包装原始函数的新函数并进行日志记录。

你的输出是一样的,因为你在装饰之后只调用了一次函数。

【讨论】:

    【解决方案2】:

    为什么第一张图定义了多个包装函数?

    decorator 被传递给它正在装饰的函数;然后将其封装在wrapper 函数中,因此得名。

    图像 1 与执行图像 2 中的操作没有什么不同(如果您不需要使用包装函数):

    def log(func):
        return func('hello there')
    
    @log
    def now(msg):
        print(msg)
    

    在给出的示例中,没有特别需要使用wrapper,尽管有些情况需要使用wrapper 函数。 - 注意:当你包装一个函数时,你隐含地用另一个函数替换了一个函数。

    【讨论】:

      猜你喜欢
      • 2021-12-12
      • 2019-08-03
      • 1970-01-01
      • 2020-02-03
      • 2020-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-02-06
      • 2017-11-16
      相关资源
      最近更新 更多