前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 闭包- 胖子老板:一包槟榔 + x 包蓝利群要多少钱

Python 闭包- 胖子老板:一包槟榔 + x 包蓝利群要多少钱

作者头像
Devops海洋的渔夫
发布2019-06-02 13:49:57
5340
发布2019-06-02 13:49:57
举报
文章被收录于专栏:Devops专栏Devops专栏

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

代码语言:javascript
复制
## 定义一个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

什么是闭包

通过一个函数调用另一个函数,然后再次返回两个函数的结果集,就是闭包。那么这种方式有什么用呢? 下面先来看看一个闭包的示例。

代码语言:javascript
复制
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 都是变量,不能写死。要适当地变化。 先写个示例把。

代码语言:javascript
复制
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]: 

从上面的示例来看,虽然说三个变量,但是每次都要填写三个变量,总感觉很累。 因为槟榔和蓝利群的价格基本不变,就偶尔变一下。

能否写得简单一些,在需要变化价格的时候,再输入价格参数,其余的时间都写购买蓝利群的数量即可呢?

代码语言:javascript
复制
## 定义全局变量,这样就不用经常写这两个参数了。
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]: 

从上面来看,使用全局变量的确挺简单,但是有个缺点,这个全局变量是可以在任意地方都修改。没有比较好的封闭,这样的话,一个不注意可能就会出错。

能够再写得封闭一些呢?用类来实现可不可以呢?

代码语言:javascript
复制
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

从上面来看,使用类也可以比较好地实现,只要槟榔和蓝利群的价格变更,此时只要重建一个类对象,再计算,就可以啦。

但是要知道,创建一个类其实很浪费资源的,因为一个类里面有各种魔法属性。那么有没有什么方法既省资源,又可以方便地实现这种封闭性的调用呢?

答案:就是闭包。 下面使用闭包的方式,再写一次。

代码语言:javascript
复制
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]: 

这种方式就是闭包,使用最简洁的方式,调用这种需要提前设定一部分形参的方法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.01.01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在讲闭包之前,首先要理解一下函数的调用
  • 什么是闭包
  • 闭包的探讨 - 胖子老板:一包槟榔 + x 包蓝利群要多少钱
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档