仅供学习,转载请注明出处
在讲闭包之前,首先要理解一下函数的调用
## 定义一个pay函数
In [7]: def pay1():
...: print("胖子老板:一包蓝利群!")
...:
In [8]: pay1()
胖子老板:一包蓝利群!
## 在这里要注意,函数的指向传递,注意不要加(),加了()就是返回执行的结果
## 而没有()则是将指向函数处理代码的内存地址传递给ret
In [9]: ret = pay1
## 下面查看一下内存地址检查一下
In [10]: id(ret)
Out[10]: 2547915405376
In [11]: id(pay1)
Out[11]: 2547915405376
## 测试执行一下
In [12]: ret()
胖子老板:一包蓝利群!
In [13]:
好了,通过上面的执行,可以知道函数的传递是使用这个方式的ret = pay1
,也就是
变量1 = 函数1
。
什么是闭包
通过一个函数调用另一个函数,然后再次返回两个函数的结果集,就是闭包。那么这种方式有什么用呢?
下面先来看看一个闭包的示例。
In [14]: def fatBoss(hobby):
...: # 在胖子老板的函数内,再定义一个函数
...: def fatBossGirl(hobby2):
...: return "胖子老板的爱好%s ,胖子老板女儿的爱好%s" % (hobby,hobby2)
...: return fatBossGirl
...:
## 在定义fatBoss函数的时候,首先将"斗地主"传递给 hobby 参数
In [15]: ret = fatBoss("斗地主")
## 因为 ret = fatBoss ,那么就等价于 ret = fatBossGirl ,
In [17]: print(ret("打麻将"))
胖子老板的爱好斗地主 ,胖子老板女儿的爱好打麻将
In [18]:
那么为什么要用这种写法呢?
其实主要原因是为了简洁以及节省资源,下面来看看一个例子,看看哪种写法最好。
闭包的探讨 - 胖子老板:一包槟榔 + x 包蓝利群要多少钱
这是什么鬼题目针对这个需求,首先公式写出来先: price = binlang_price + num * lanliqun_price
在知道闭包之前,该怎么计算这个价格呢?
首先 binlang_price \ num \ lanliqun_price
都是变量,不能写死。要适当地变化。
先写个示例把。
In [18]: def price(binlang_price,lanliqun_price,num):
...: return binlang_price + (num * lanliqun_price )
...:
In [19]: p = price(10,17,1)
In [20]: print(p)
27
In [21]:
从上面的示例来看,虽然说三个变量,但是每次都要填写三个变量,总感觉很累。
因为槟榔和蓝利群的价格基本不变,就偶尔变一下。
能否写得简单一些,在需要变化价格的时候,再输入价格参数,其余的时间都写购买蓝利群的数量即可呢?
## 定义全局变量,这样就不用经常写这两个参数了。
In [21]: binlang_price = 10
In [22]: lanliqun_price = 17
In [23]: def price(num):
...: global binlang_price
...: global lanliqun_price
...: return binlang_price + (num * lanliqun_price )
...:
In [24]: p = price(1)
In [25]: print(p)
27
In [26]:
从上面来看,使用全局变量的确挺简单,但是有个缺点,这个全局变量是可以在任意地方都修改。没有比较好的封闭,这样的话,一个不注意可能就会出错。
能够再写得封闭一些呢?用类来实现可不可以呢?
In [29]: class Price(object):
...: def __init__(self,binlang_price,lanliqun_price):
...: self.binlang_price = binlang_price
...: self.lanliqun_price = lanliqun_price
...: def __call__(self,num):
...: return self.binlang_price + (num * self.lanliqun_price)
...:
In [30]: p = Price(10,17)
In [31]: p(1)
Out[31]: 27
In [32]: p(2)
Out[32]: 44
从上面来看,使用类也可以比较好地实现,只要槟榔和蓝利群的价格变更,此时只要重建一个类对象,再计算,就可以啦。
但是要知道,创建一个类其实很浪费资源的,因为一个类里面有各种魔法属性。那么有没有什么方法既省资源,又可以方便地实现这种封闭性的调用呢?
答案:就是闭包。
下面使用闭包的方式,再写一次。
In [33]: def Price(binlang_price,lanliqun_price):
...: def caculate(num):
...: return binlang_price + (num * lanliqun_price)
...: return caculate
...:
In [34]: p = Price(10,17)
In [35]: p(1)
Out[35]: 27
In [36]: p(2)
Out[36]: 44
In [37]:
这种方式就是闭包,使用最简洁的方式,调用这种需要提前设定一部分形参的方法。
关注微信公众号,回复【资料】、Python、PHP、JAVA、web,则可获得Python、PHP、JAVA、前端等视频资料。
网友评论