(通过将原来代码作为函数,传入装饰器,返回新的结果)
import time
def time_master(func):
def call_func():
print("开始运行程序...")
start = time.time()
func()
stop= time.time()
print("结束程序运行...")
print(f"一共耗费了 {(stop-start):.2f} 秒.")
return call_func
@time_master
def myfunc():
time.sleep(2)
print("Hello Python.")
myfunc()
>>>
开始运行程序...
Hello Python.
结束程序运行...
一共耗费了 2.13 秒.
此外,多个装饰器可以用在同一个函数上,还可以通过函数的多层嵌套调用给装饰器传递参数。
(多个@装饰器时,执行顺序是从下往上)
def square(func):
def inner():
x = func()
return x ** 2
return inner
def add(func):
def inner():
x = func()
return x + 3
return inner
@square
@add
def test():
return 2
print(test()) # 顺序为(2+3)** 2
>>>
25
装饰器也可以传入参数。
import time
def logger(msg):
def time_master(func):
def inner():
start = time.time()
func()
stop= time.time()
print(f"[{msg}]一共耗费了 {(stop-start):.2f} 秒.")
return inner
return time_master
@logger(msg='A') # 等同于funA = logger(msg=‘A’)(funA)
def funA():
print("正在运行程序funA...")
time.sleep(1)
@logger(msg='B')
def funB():
print("正在运行程序funB...")
time.sleep(2)
funA()
funB()
>>>
正在运行程序funA...
一共耗费了 1.08 秒.
正在运行程序funB...
一共耗费了 2.03 秒. import time
def logger(msg):
def time_master(func):
def useless():
def call_func():
start = time.time()
func()
stop = time.time()
print(f"[{msg}]一共耗费了 {(stop-start):.2f}")
return call_func
return useless()
return time_master
@logger(msg="A")
def funA():
time.sleep(1)
print("正在调用funA...")
@logger(msg="B")
def funB():
time.sleep(1)
print("正在调用funB...")
funA()
funB()
第三个知识点让我好奇,这个语法糖是否可以不断向内挖掘嵌套函数,直到挖到最底层函数,然后将这个最底层的函数赋值给原函数?
这里在在logger函数中间添加了一个useless用来检测,经过实践确实是这样的,我随后还试了试两个useless,也是同样的结果
正在调用funA...
一共耗费了 1.01
正在调用funB...
一共耗费了 1.00 装饰器第一部分的闭包过程中不打 return call_func为什么报错 需要注意的是 ‘return 函数名’ 的后面是否加‘()’
def cube(func):
def inner():
def a():
def b():
x = func()
return x * x * x
return b()
return a()
return inner
@cube
def test():
return 2
print(test())
等价于
def cube(func):
def inner():
def a():
def b():
x = func()
return x * x * x
return b
return a
return inner
@cube
def test():
return 2
print(test()()())
我觉得可以这么理解语法糖
import time
def time_master(func):
def call_func():
print('开始运行程序...')
start = time.time()
func() # 函数嵌套调用 func是形参,myfunc是实参因此这里会执行myfunc()函数
stop = time.time()
print('结束程序运行...')
print(f'一共耗费了{(stop-start):.2f}秒')
return call_func # 嵌套函数的返回值 返回到>>>函数调用处
def myfunc():
time.sleep(2)
print('Python')
a = time_master(myfunc) #这是函数调用处》》也就是说 a = time_master(myfunc)就是call_func
a() # 所以这里就是 call_func() 8245k 发表于 2022-8-1 23:41
第三个知识点让我好奇,这个语法糖是否可以不断向内挖掘嵌套函数,直到挖到最底层函数,然后将这个最底层 ...
我认为是由于func()这个嵌套调用在最最内存函数call_func()中,所以最后实质上才是call_func()这个函数的实现 本帖最后由 阿伟同学 于 2022-9-28 21:23 编辑
8245k 发表于 2022-8-1 23:41
第三个知识点让我好奇,这个语法糖是否可以不断向内挖掘嵌套函数,直到挖到最底层函数,然后将这个最底层 ...
问题不在这,是您retrun useless() 加上括号了{:10_263:}按小甲鱼等价的
funA = logger(msg = "A")(funA)你这个相当于还是返回call_func的引用,你要是把括号去了就大不一样了 难成狗啊,我要多看几次才行,坚持把这吃透 装饰器,确实很强大, 但是理解起来确实比较费力,继续加油
滴滴滴~打卡{:10_298:} 测试函数不能带参数,不然会报错,这是为什么呢?比如只能funA(),而不能是funA(x){:10_269:} 8245k 发表于 2022-8-1 23:41
第三个知识点让我好奇,这个语法糖是否可以不断向内挖掘嵌套函数,直到挖到最底层函数,然后将这个最底层 ...
不会把,装饰器只会将函数作为参数传一次,你一直往下嵌套直到最底层,是因为你返回函数的时候加了() 语法糖很赞啊 装饰器相对于语法糖,但是看起来更简洁直接 Learning... 七钱五 发表于 2022-10-16 16:47
测试函数不能带参数,不然会报错,这是为什么呢?比如只能funA(),而不能是funA(x)
我也遇到了同样的问题,想知道后面怎么解决了?{:10_285:} {:10_266:} 打卡
页:
[1]
2