作家
登录

程序员必知的Python陷阱与缺陷列表

作者: 来源: 2017-08-04 05:40:07 阅读 我要评论

第六,闭包与lambda

这个也是老发展谈的例子,在其他说话也有类似的情况。先看一个例子:

  1. >>> def create_multipliers(): 
  2.  
  3. ... return [lambda x:i*x for i in range(5)] 
  4.  
  5. ... 
  6.  
  7. >>> for multiplier in create_multipliers(): 
  8.  
  9. ... print multiplier(2) 
  10.  
  11. ...  

create_multipliers函数的返回值时一个列表,列表的每一个元素都是一个函数 -- 将输入参数x乘以一个倍数i的函数。预期的结不雅时0,2,4,6,8. 但结不雅是5个8,不测不料外。

因为出现这个陷阱的时刻经常应用了lambda,所以可能会认为是lambda的问题,但lambda表示不肯意背这个锅。问题的本质在与python中的属性查找规矩,LEGB(local,enclousing,global,bulitin),在膳绫擎的例子中,i就是在闭包感化域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包顶用到的变量的值,是在内部函数被调用时萌芽获得的。

解决办法也很简单,那就是变闭包感化域为局部感化域。

  1. >>> def create_multipliers(): 
  2.  
  3. ... return [lambda x, i = i:i*x for i in range(5)] 
  4.  
  5. ...  

第七,定义__del__

  1. >>> def f(lst = []): 
  2.  
  3. ...     lst.append(1) 
  4.  
  5. ...     return lst 
  6.  
  7. ... 
  8.  
  9. >>> f() 
  10.  
  11. [1] 
  12.  
  13. >>> f() 
  14.  
  15. [1, 1]  

大年夜多半计算机专业的同窗可能都是先学的C、C++,构造、析构函数的概念应当都异常熟。于是,当切换到python的时刻,天然也想知道有没有响应的函数。比如,在C++中异常有名的RAII,即经由过程构造、析构来治理资本(如内存、文件描述符)的声明周期。那在python中要达到同样的效不雅怎么做呢,即须要找到一个对象在烧毁的时刻必定会调用的函数,于是发清楚明了__init__, __del__函数,可能简单写了两个例子发明白实也能工作。但事实上可能掉落进了一个陷阱,在python documnet是有描述的:

main.py代码如下:

  1. def add(x): 
  2.  
  3. from mypackage import mymodule 
  4.  
  5. mymodule.l.append(x) 
  6.  
  7. print "updated list",mymodule.l, id(mymodule) 
  8.  
  9. def get(): 
  10.  
  11. import mymodule 
  12.  
  13. print 'module in get', id(mymodule) 
  14.  
  15. return mymodule.l 
  16.  
  17. if __name__ == '__main__'
  18.  
  19. import sys 
  20.  
  21. sys.path.append('../'
  22.  
  23. add(1) 
  24.  

      推荐阅读

      有效促进物联网安全的5大策略

    跟着物联网设备的赓续出现,用户所碰到的严重的物联网安然问题不容忽视。分析师和专家经常评论辩论这个严重问题,人们须要采取积极主动的行动来竽暌功对和解决。根据调研机构Gartner公司的>>>详细阅读


    本文标题:程序员必知的Python陷阱与缺陷列表

    地址:http://www.17bianji.com/lsqh/36531.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)