第六,闭包与lambda
这个也是老发展谈的例子,在其他说话也有类似的情况。先看一个例子:
- >>> def create_multipliers():
- ... return [lambda x:i*x for i in range(5)]
- ...
- >>> for multiplier in create_multipliers():
- ... print multiplier(2)
- ...
create_multipliers函数的返回值时一个列表,列表的每一个元素都是一个函数 -- 将输入参数x乘以一个倍数i的函数。预期的结不雅时0,2,4,6,8. 但结不雅是5个8,不测不料外。
因为出现这个陷阱的时刻经常应用了lambda,所以可能会认为是lambda的问题,但lambda表示不肯意背这个锅。问题的本质在与python中的属性查找规矩,LEGB(local,enclousing,global,bulitin),在膳绫擎的例子中,i就是在闭包感化域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包顶用到的变量的值,是在内部函数被调用时萌芽获得的。
解决办法也很简单,那就是变闭包感化域为局部感化域。
- >>> def create_multipliers():
- ... return [lambda x, i = i:i*x for i in range(5)]
- ...
第七,定义__del__
- >>> def f(lst = []):
- ... lst.append(1)
- ... return lst
- ...
- >>> f()
- [1]
- >>> f()
- [1, 1]
大年夜多半计算机专业的同窗可能都是先学的C、C++,构造、析构函数的概念应当都异常熟。于是,当切换到python的时刻,天然也想知道有没有响应的函数。比如,在C++中异常有名的RAII,即经由过程构造、析构来治理资本(如内存、文件描述符)的声明周期。那在python中要达到同样的效不雅怎么做呢,即须要找到一个对象在烧毁的时刻必定会调用的函数,于是发清楚明了__init__, __del__函数,可能简单写了两个例子发明白实也能工作。但事实上可能掉落进了一个陷阱,在python documnet是有描述的:
main.py代码如下:
- def add(x):
- from mypackage import mymodule
- mymodule.l.append(x)
- print "updated list",mymodule.l, id(mymodule)
- def get():
- import mymodule
- print 'module in get', id(mymodule)
- return mymodule.l
- if __name__ == '__main__':
- import sys
- sys.path.append('../')
- add(1)
推荐阅读
跟着物联网设备的赓续出现,用户所碰到的严重的物联网安然问题不容忽视。分析师和专家经常评论辩论这个严重问题,人们须要采取积极主动的行动来竽暌功对和解决。根据调研机构Gartner公司的>>>详细阅读
本文标题:程序员必知的Python陷阱与缺陷列表
地址:http://www.17bianji.com/lsqh/36531.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示