标签:pad microsoft attr man data- sof tom 装饰器 闭包
函数装饰器和闭包
自定义一个装饰器
>>> def deco(func):
... def inner():
... print(‘running inner()‘)
... return inner
...
>>> @deco
... def target():
... print(‘running target()‘)
...
>>> target()
running inner()
>>> target
<function deco.<locals>.inner at 0x7fd604acd1e0>
"""
练习装饰器
2019年11月16日
作者:戴昊龙
"""
regis = []
def registry(func):
print("running registry %s" % func)
regis.append(func)
return func
def func1():
print("running func1")
def func2():
print("running func2")
def func3():
print("running func3")
def main():
print("running main")
print("regis---->", regis)
func1()
func2()
func3()
if __name__ == ‘__main__‘:
main()
running registry <function func1 at 0x0000000002207A60>
running registry <function func2 at 0x0000000002207EA0>
running main
regis----> [<function func1 at 0x0000000002207A60>, <function func2 at 0x0000000002207EA0>]
running func1
running func2
running func3
>>> b = 6
>>> def test():
... a = 9
... print(a)
... print(b)
... b = 10
...
>>> test()
9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in test
UnboundLocalError: local variable ‘b‘ referenced before assignment
>>> def f():
... a = 9
... print(a)
... global b
... print(b)
... b =10
...
>>> f()
9
6
>>> b
10
# 比方说一个avg函数,用来实现移动求平均
# 每次都叠加求平均
avg(10) ---- 10.0
avg(11)----- 10.5
avg(12)------11.0
# 怎么来实现呢? 普通的应该就是用类和对象来实现,第二种方法可以用高阶函数来实现
# example(1),用类来实现
class Average():
def __init__(self):
self.series = []
def __call__(self, new_value):
self.series.append(new_value)
total = sum(self.series)
return total/len(self.series)
a1 = Average()
print(a1(10))
# example(2), 用高阶函数实现
def make_averager(): # example2
series = [] # 这个就是闭包
def average(num):
series.append(num) # series是自由变量
total = sum(series)
return total/len(series)
return average # 每次返回的是一个函数对象
a1 = make_averager()
print(a1(10))
print(a1(20))
# example(3), 例2中,其实函数的效率不是很高,因为每次都在重复的求取sum,len, 这里我们可以改进一下
def make_average():
count = 0
total = 0
def average(num):
nonlocal count, total # 没有这句声明那这个example3就是错的,为什么呢?
"""
数字、字符串、元组等不可变类型来说,只能读取,不能更新。如果尝试重新绑
定,例如 count = count + 1 ,其实会隐式创建局部变量 count 。这样, count 就不是自由 怎么理解这段话?
变量了,因此不会保存在闭包中。
当i = 10的时候。 实际上 i += 1 并不是真的在原有的int对象上+1,而是重新创建一个value为 11 的int对象,i引用自这个新的对象。
"""
count += 1
total = total + num
return total/count
return average
"""
nonlocal 它的作用是把变量标记为自由变量,
即使在函数中为变量赋予新值了,也会变成自由变量。如果为 nonlocal 声明的变量赋予新值,闭包中保存的绑定会更新。
"""
标签:pad microsoft attr man data- sof tom 装饰器 闭包
原文地址:https://www.cnblogs.com/dadaizi/p/13060432.html