python中闭包局部、全局变量的使用

  • 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值