初闻此名,以为是哪个程序猿代码写久了,成了自闭症,把自己封闭起来包起来,觉得真逗。
闭包原来是指一类特殊的函数,这类函数是为了不修改其它函数而为了给其它函数增加某些功能而巧妙地设计出来的。
巧在哪里?妙在哪里?就让我们来看看以下场景吧。
公司小欧写了个函数如下:
1 def say(): 2 print("老板是个二货")
你猜对了,小欧准备删库跑路,最后折腾下这个死扣老板,只要程序执行了公司的重要函数就会显示“老板是个二货”,于是他想到了一个办法,
只需要在公司程序里用闭包给巧妙地把函数给伪装起来,神不知鬼不觉地就达到了目的。于是,小欧把以上代码悄悄修改了下。
1 def goodman(fun): #这个就是小欧写的闭包代码 2 def say(*args, **kwargs): 3 print("老板是个二货") 4 return fun(*args, **kwargs) 5 return say 6 7 8 def num_sum(a, b): #公司最重要的一个函数 9 return a + b 10 11 num_sum = goodman(num_sum)#将函数伪装起来 12 13 a = num_sum(1, 2) 14 print(a) 15 16 #运行结果: 17 老板是个二货 18 3
小欧的强项就是偷懒,他觉得每次敲键盘得累死,于是又用了装饰器来减轻他“犯罪”的劳力。
#小欧用装饰器来简化操作 @goodman #在函数上加了一个@goodman == “num_sum = goodman(num_sum) ”少写了一些字而已 def num_sum(a, b): return a + b a = num_sum(1, 2) print(a) #运行结果: 老板是个二货 3
小欧觉得还不过瘾,在使用程序中,让老板是唯一一个蒙在鼓里的人,那么就更爽了。
1 def check(name): #外面再套一层检验登录的是否是老板 2 def goodman(fun): 3 def say(*args, **kwargs): 4 if name != "BOSS": #只要不是老板登录就显示"老板是二货" 5 print("老板是个二货") 6 return fun(*args, **kwargs) 7 return say 8 return goodman 9 10 @check(name = "BOSS") 11 def num_sum(a, b): # 公司最重要的一个函数 12 return a + b 13 14 a = num_sum(1, 2) 15 print(a) 16 17 # 运行结果: 18 3
小欧一看,太棒了,现在除了老板看不到,其他人都能看到“老板是二货”这句话了。
但是,小欧还留了个心眼,为了伪装得更加像,更不易被其他程序猿察觉,小欧想到了用@wraps,来伪装得更像
1 from functools import wraps #导入functools模块的wraps(超级迷彩服) 2 3 def check(name): #外面再套一层检验登录的是否是老板 4 def goodman(fun): 5 @wraps(fun) 6 def say(*args, **kwargs): 7 if name != "BOSS": #只要不是老板登录就显示"老板是二货" 8 print("老板是个二货") 9 print(fun.__name__) #看看原始函数名 10 return fun(*args, **kwargs) 11 return say 12 return goodman 13 14 @check(name = "BOSS") 15 def num_sum(a, b): # 公司最重要的一个函数 16 return a + b 17 18 a = num_sum(1, 2) 19 print(num_sum.__name__)#看看伪装后的函数名 20 print(a) 21 22 # 运行结果: 23 num_sum #原始函数名 24 num_sum #伪装后的函数名 25 3
小欧对着屏幕脸上露出了邪恶的笑容。。。。。。。。。
总结:
闭包其实就是通过函数的嵌套,赋值,讲嵌套的函数分配在内存里以便调用,装饰器本质上就是闭包,只是美其名曰装饰器,其实应该叫伪装器更为恰当。Python意为蟒蛇,蟒蛇就有伪装隐藏的本能,通过@符号 简化了嵌套函数的赋值代码,并且可以使用 @wraps功能 将嵌套函数伪装得天衣无缝。
当然 装饰器还有Python的内置装饰器
@staticmathod
@classmethod
@property
这些都是后话了。。。。