- python 中局部变量没有初始化
In [4]: def log(func):
...: time=0
...: def wrapper(*arg,**kw):
...: print("call %s()"%func.__name__)
...: time+=1
...: print("---time----:",time)
...: #return func(*args,**kw)
...: return wrapper
In [5]: @log
...: def now():
...: print("---test----")
In [6]: now()
call now()
UnboundLocalError: local variable 'time' referenced before assignment
- 定义为nonlocal
In [9]: def log(func):
...: time=0
...: def wrapper(*arg,**kw):
...: print("call %s()"%func.__name__)
...: nonlocal time
...: time+=1
...: print("---time----:",time)
...: #return func(*args,**kw)
...: return wrapper
In [10]: @log
...: def now():
...: print("---test----")
In [11]: now()
call now()
---time----: 1
In [12]: now()
call now()
---time----: 2
In [13]: now()
call now()
---time----: 3
- 有返回值的闭包
In [22]: def log(func):
...: time=0
...: time+=1
...: print("----log---time:",time)
...: def wrapper(*arg,**kw):
...: print("call %s()"%func.__name__)
...: time2=5
...: time2+=1
...: print("---time----:",time)
...: return func(*arg,**kw)
...: return wrapper
In [23]: @log
...: def now():
...: print("---test----")
----log---time: 1
In [24]: now()
call now()
---time----: 1
---test----
In [25]: now()
call now()
---time----: 1
---test----
分析
now 是指向 print("—test–")函数体1,@log 执行now=log(now),此时func指向函数体1,且返回wrapper函数体2的引用,即now指向函数体2;now()则调用wrapper()函数体2,函数体2返回func函数的引用,即调用函数体2
In [52]: def log(text):
...: print("---日志--")
...: def decorator(func):
...: print("---test__")
...: def wrapper(*args,**kw):
...: print("%s %s ()" % (text,func.__name__))
...: return func(*args,**kw)
...: return wrapper
...: return decorator
In [53]: @log("execute")
...: def now():
...: print("I love you ")
---日志--
---test__
In [54]: #此处相当于now=log("execute")(now)
In [55]: now()
execute now ()
I love you
In [56]: now.__name__
Out[56]: 'wrapper'
Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展。但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题。Python 通过 functool.wraps 为我们解决了这个问题:在编写装饰器时,在实现前加入 @functools.wraps(func) 可以保证装饰器不会对被装饰函数造成影响
In [60]: def log(text):
...: print("---日志--")
...:
...: def decorator(func):
...: print("---test__")
...: @functools.wraps(func)
...: def wrapper(*args,**kw):
...: print("%s %s ()" % (text,func.__name__))
...: return func(*args,**kw)
...: return wrapper
...: return decorator
In [61]: @log("execute")
...: def now():
...: print("I love you ")
---日志--
---test__
In [62]: now()
execute now ()
I love you
In [64]: now.__name__
Out[64]: 'now'
参考:https://blog.csdn.net/foryouslgme/article/details/51508416