Discuss / Python / 有没有大佬帮我看看我的疑问

有没有大佬帮我看看我的疑问

Topic source

为什么要多此一举的写def wrapper(): return func()呢?

def metric(fn):
    def wrapper(*args, **kw):
        print('%s executed in %s ms' % (func.__name__,10.24))
        return fn(*args, **kw)
    return wrapper

直接写成这样不就好了?

def metric(fn):

    print('%s executed in %s ms' % (fn.__name__, 10.24))

    return fn

难道装饰器非要加上wrapper()才能算装饰器吗?直接写成后者并且在函数fn()前@难道不算装饰器吗?

还有一个疑问就是:

now = log(now)

由于log()是一个decorator,返回一个函数,所以,原来的now()函数仍然存在,只是现在同名的now变量指向了新的函数,于是调用now()将执行新函数,即在log()函数中返回的wrapper()函数。

这中间讲的now指向一个新函数,那Python解释器是怎么知道调用now时是调用新函数还是旧函数

ZzzgnzzZ

#3 Created at ... [Delete] [Delete and Lock User]

1. 修饰器的作用是增强函数的功能。用你的方法,fn依然指向fn本身,没有变化。

2. 调用哪个函数取决于你的代码。在def now()上面一行加了@修饰器,就会调用新函数。def now()上面没有修饰器,就不存在新函数了。

ZzzgnzzZ

#4 Created at ... [Delete] [Delete and Lock User]

你做的结果是错的,你需要写语句来print函数的运行时间,题里的10.24只是随便给的一个数字

吟游之狼

#5 Created at ... [Delete] [Delete and Lock User]

1、这种写法没有传入func的参数。装饰器实际是先传入func函数的定义,然后传入了调用func函数时的参数。
2、新的指向会覆盖旧的指向,所以解释器肯定是调用最后指向的那个

闭包先搞清楚再来学装饰器

紆崽man

#7 Created at ... [Delete] [Delete and Lock User]

@log 好像是对之后定义的函数如func(),将func()传入到定义的log函数中,执行一次log函数,然后将返回的值重新赋给func,如下:

>>> def log(func):
	print(func.__name__)
	return "a"

>>> @log
def funct():
	pass

funct
>>> print(funct)
a
>>> funct
'a'

可以看到@log 后定义完函数后执行了print(func.__name__),输出了函数名funct,定义的函数再也变成了log函数的返回值"a"。这也是为什么“经过decorator装饰之后的函数,它们的__name__已经从原来的'now'变成了'wrapper'”。

所以这样的语法下就应该需要定义一个wrapper()这样的函数。

看完我也是似懂非懂,自己去试过了才明白这都是什么,还是要看看大佬们的评论。

全麦201706

#8 Created at ... [Delete] [Delete and Lock User]

不用闭包的话不是不行 但不是最好的方法

https://www.tuicool.com/articles/FBZvya


  • 1

Reply