仅供学习,转载请注明出处

在讲闭包之前,首先要理解一下函数的调用

## 定义一个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 包蓝利群要多少钱

Python 闭包- 胖子老板:一包槟榔 + 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 闭包- 胖子老板:一包槟榔 + x 包蓝利群要多少钱_python_02