美文网首页
Python 闭包- 胖子老板:一包槟榔 + x 包蓝利群要多少

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

作者: Devops海洋的渔夫 | 来源:发表于2019-01-01 22:37 被阅读35次

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

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

    ## 定义一个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、前端等视频资料。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/glmolqtx.html