说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

Python开发者最常犯的10个错误

HTML文档下载 WORD文档下载 PDF文档下载
Python是一门简单易学的编程语言,语法简洁而清晰,并且拥有丰富和强大的类库。在日常开发中,开发者很容犯一些低级的错误,本文总结了开发者最容易犯的10个错误。

Python是一门简单易学的编程语言,语法简洁而清晰,并且拥有丰富和强大的类库。与其它大多数程序设计语言使用大括号不一样 ,它使用缩进来定义语句块。

在平时的工作中,Python开发者很容易犯一些小错误,这些错误都很容易避免,本文总结了Python开发者最常犯的10个错误,一起来看下,不知你中枪了没有。


1.滥用表达式作为函数参数默认值

Python允许开发者指定一个默认值给函数参数,虽然这是该语言的一个特征,但当参数可变时,很容易导致混乱,例如,下面这段函数定义:

>>> def foo(bar=[]):        # bar is optional and defaults to [] if not specified...    bar.append("baz")    # but this line could be problematic, as we'll see......    return bar

在上面这段代码里,一旦重复调用foo()函数(没有指定一个bar参数),那么将一直返回'bar',因为没有指定参数,那么foo()每次被调用的时候,都会赋予[]。下面来看看,这样做的结果:

>>> foo()["baz"]>>> foo()["baz", "baz"]>>> foo()["baz", "baz", "baz"]
解决方案:

>>> def foo(bar=None):...    if bar is None:		# or if not bar:...        bar = []...    bar.append("baz")...    return bar...>>> foo()["baz"]>>> foo()["baz"]>>> foo()["baz"]
2.错误地使用类变量

先看下面这个例子:

>>> class A(object):...     x = 1...>>> class B(A):...     pass...>>> class C(A):...     pass...>>> print A.x, B.x, C.x1 1 1
这样是有意义的:

>>> B.x = 2>>> print A.x, B.x, C.x1 2 1
再来一遍:

>>> A.x = 3>>> print A.x, B.x, C.x3 2 3
仅仅是改变了A.x,为什么C.x也跟着改变了。

在Python中,类变量都是作为字典进行内部处理的,并且遵循方法解析顺序(MRO)。在上面这段代码中,因为属性x没有在类C中发现,它会查找它的基类(在上面例子中只有A,尽管Python支持多继承)。换句话说,就是C自己没有x属性,独立于A,因此,引用 C.x其实就是引用A.x。

3.为异常指定不正确的参数

假设代码中有如下代码:

>>> try:...     l = ["a", "b"]...     int(l[2])... except ValueError, IndexError:  # To catch both exceptions, right?...     pass...Traceback (most recent call last):  File "<stdin>", line 3, in <module>IndexError: list index out of range

问题在这里,except语句并不需要这种方式来指定异常列表。然而,在Python 2.x中,except Exception,e通常是用来绑定异常里的 第二参数,好让其进行更进一步的检查。因此,在上面这段代码里,IndexError异常并没有被except语句捕获,异常最后被绑定 到了一个名叫IndexError的参数上。

在一个异常语句里捕获多个异常的正确方法是指定第一个参数作为一个元组,该元组包含所有被捕获的异常。与此同时,使用as关键字来保证最大的可移植性,Python 2和Python 3都支持该语法。

>>> try:...     l = ["a", "b"]...     int(l[2])... except (ValueError, IndexError) as e:  ...     pass...>>>
4.误解Python规则范围

Python的作用域解析是基于LEGB规则,分别是Local、Enclosing、Global、Built-in。实际上,这种解析方法也有一些玄机,看下面这个例子:

>>> x = 10>>> def foo():...     x += 1...     print x...>>> foo()Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 2, in fooUnboundLocalError: local variable 'x' referenced before assignment

许多人会感动惊讶,当他们在工作的函数体里添加一个参数语句,会在先前工作的代码里报UnboundLocalError错误( 点击这里查看更详细描述)。

在使用列表时,开发者是很容易犯这种错误的,看看下面这个例子:

>>> lst = [1, 2, 3]>>> def foo1():...     lst.append(5)   # This works ok......>>> foo1()>>> lst[1, 2, 3, 5]>>> lst = [1, 2, 3]>>> def foo2():...     lst += [5]      # ... but this bombs!...>>> foo2()Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 2, in fooUnboundLocalError: local variable 'lst' referenced before assignment
为什么foo2失败而foo1运行正常?

答案与前面那个例子是一样的,但又有一些微妙之处。foo1没有赋值给lst,而foo2赋值了。lst += [5]实际上就是lst = lst + [5],试图给lst赋值(因此,假设Python是在局部作用域里)。然而,我们正在寻找指定给lst的值是基于lst本身,其实尚未确定。

5.修改遍历列表

下面这段代码很明显是错误的:

>>> odd = lambda x : bool(x % 2)>>> numbers = [n for n in range(10)]>>> for i in range(len(numbers)):...     if odd(numbers[i]):...         del numbers[i]  # BAD: Deleting item from a list while iterating over it...Traceback (most recent call last):  	  File "<stdin>", line 2, in <module>IndexError: list index out of range
在遍历的时候,对列表进行删除操作,这是很低级的错误。稍微有点经验的人都不会犯。

对上面的代码进行修改,正确地执行:

>>> odd = lambda x : bool(x % 2)>>> numbers = [n for n in range(10)]>>> numbers[:] = [n for n in numbers if not odd(n)]  # ahh, the beauty of it all>>> numbers[0, 2, 4, 6, 8]
6.如何在闭包中绑定变量

看下面这个例子:

>>> def create_multipliers():...     return [lambda x : i * x for i in range(5)]>>> for multiplier in create_multipliers():...     print multiplier(2)...
你期望的结果是:

<code>02468</code>
实际上:

<code>88888</code>
是不是非常吃惊!出现这种情况主要是因为Python的后期绑定行为,该变量在闭包中使用的同时,内部函数又在调用它。

解决方案:

>>> def create_multipliers():...     return [lambda x, i=i : i * x for i in range(5)]...>>> for multiplier in create_multipliers():...     print multiplier(2)...02468
7.创建循环模块依赖关系

假设有两个文件,a.py和b.py,然后各自导入,如下:

在a.py中:

import bdef f():    return b.x	print f()
在b.py中:

import ax = 1def g():    print a.f()
首先,让我们试着导入a.py:

<code>>>> import a1</code>

可以很好地工作,也许你会感到惊讶。毕竟,我们确实在这里做了一个循环导入,难道不应该有点问题吗?

仅仅存在一个循环导入并不是Python本身问题,如果一个模块被导入,Python就不会试图重新导入。根据这一点,每个模块在试图访问函数或变量时,可能会在运行时遇到些问题。

当我们试图导入b.py会发生什么(先前没有导入a.py):

>>> import bTraceback (most recent call last):  	  File "<stdin>", line 1, in <module>  	  File "b.py", line 1, in <module>    import a  	  File "a.py", line 6, in <module>	print f()  	  File "a.py", line 4, in f	return b.xAttributeError: 'module' object has no attribute 'x'

出错了,这里的问题是,在导入b.py的过程中还要试图导入a.py,这样就要调用f(),并且试图访问b.x。但是b.x并未被定义。

可以这样解决,仅仅修改b.py导入到a.py中的g()函数:

x = 1def g():    import a	# This will be evaluated only when g() is called    print a.f()
无论何时导入,一切都可以正常运行:

>>> import b>>> b.g()1	# Printed a first time since module 'a' calls 'print f()' at the end1	# Printed a second time, this one is our call to 'g'
8.与Python标准库模块名称冲突

Python拥有非常丰富的模块库,并且支持“开箱即用”。因此,如果不刻意避免,很容易发生命名冲突事件。例如,在你的代码中可能有一个email.py的模块,由于名称一致,它很有可能与Python自带的标准库模块发生冲突。

9.未按规定处理Python2.x和Python3.x之间的区别

看一下foo.py:

import sysdef bar(i):    if i == 1:        raise KeyError(1)    if i == 2:        raise ValueError(2)def bad():    e = None    try:        bar(int(sys.argv[1]))    except KeyError as e:        print('key error')    except ValueError as e:        print('value error')    print(e)bad()
在Python 2里面可以很好地运行:

$ python foo.py 1key error1$ python foo.py 2value error2
但是在Python 3里:

$ python3 foo.py 1key errorTraceback (most recent call last):  File "foo.py", line 19, in <module>    bad()  File "foo.py", line 17, in bad    print(e)UnboundLocalError: local variable 'e' referenced before assignment
解决方案:

import sysdef bar(i):    if i == 1:        raise KeyError(1)    if i == 2:        raise ValueError(2)def good():    exception = None    try:        bar(int(sys.argv[1]))    except KeyError as e:        exception = e        print('key error')    except ValueError as e:        exception = e        print('value error')    print(exception)good()
在Py3k中运行结果:

<code>$ python3 foo.py 1key error1$ python3 foo.py 2value error2</code>
在 Python招聘指南里有许多关于Python 2与Python 3在移植代码时需要关注的注意事项与讨论,大家可以前往看看。

10.滥用__del__方法

比如这里有一个叫mod.py的文件:

import fooclass Bar(object):   	    ...    def __del__(self):        foo.cleanup(self.myhandle)
下面,你在another_mod.py文件里执行如下操作:

import modmybar = mod.Bar()
你会获得一个AttributeError异常。

至于为什么会出现该异常,点击这里查看详情。当解释器关闭时,该模块的全局变量全部设置为None。因此,在上面这个例子里,当__del__被调用时,foo已经全部被设置为None。

一个很好的解决办法是使用atexit.register()代替。顺便说一句,当程序执行完成后,您注册的处理程序会在解释器关闭之前停止 工作。

修复上面问题的代码:

import fooimport atexitdef cleanup(handle):    foo.cleanup(handle)class Bar(object):    def __init__(self):        ...        atexit.register(cleanup, self.myhandle)
在程序的正常终止的前提下,这个实现提供了一个整洁可靠的方式调用任何需要清理的功能。

总结

VB如何从&quot;SOUND.DRV&quot;中提取声音 VB如何设定墙纸的显示方式? VB如何用API及MMSYSTEM.DLL播放AVI文件 VB如何知道计算机是否安装声卡? 设计简单的屏幕保护程序 -VB资料 使机箱内的小喇叭发出不同的声音 -VB资料 使用VB设计具有「动感」的命令图标栏 五彩缤纷的清屏效果-VB资料 系统是否支持声音 -VB资料 一个实用的VB屏幕程序 一个自动更换墙纸的小软件-VB资料 VB用 VB 设 计 VCD 播 放 器 VB用API播放 .wav 声音文件 VB用MCI指令进行多媒体编程 用VB5.0编写自己的MP3播放器 用VB6.0编写电脑抽奖程序 用VB6的双通道技术获得影碟片断 用VBScript制作活动主页 用VB编写DirectX7.0游戏(下) 用VB编写FLASH动画播放器 用VB设计VCD播放器 用VB实现队列播放MP3 用VB实现屏幕滚屏保护效果 用VB制作下雪的特技景象 用VB自制屏幕保护程序 用Visual Basic实现多画面播放功能 雨滴式的显示图片 -VB资料 在VB5.0中制作多媒体界面 在VB5中将英文字母及阿拉伯数字旋转任意角度 在VB5中如何使机箱内的小喇叭发出不同的声音? 在VB6.0中播放GIF动画 无法创建asp.net应用程序 大家帮帮我吧,我都快崩溃了 中文乱码的问题 !!谁在VMWare 3.2里装过RedHat 9.0和RedFlag 3.0,请看看这些问题(100分)!! 如何使在输入框选中的文字在提交后仍然显示在输入框中? 无法创建asp.net应用程序 高手在上,请问怎么样在win2k中实现关闭程序和绘图[内详] 初学者问:如何在listview中查找其中一行? 怎样在调试窗口中看到变量值? 郁闷中,狂散分。。。。。。 DCOM怎么使用? 想做一个地区门户一般要包含那些栏目?? 线程 怎么能让DELPHI编出来的程序最小化以后进入到系统托盘? C++问题,请进来帮忙! help me ~!!! 以下行为究竟是关闭端口还是使用端口 callzjy(【剑客西门吹雪原来是仁者帮帮主...】) 怎么翻了这么多老帖子出来了??? 求原代码下载 大家都在干什么? 有什么东东大家可以一起研究研究? 初学者问:如何在listview中查找其中一行? fortran语言的高手请进,分数不够再加 我是一个刚刚步入JAVA世界的小鸟 恳请得到大家的帮助 。。 ActiveForm发布问题。 怎么能让DELPHI编出的程序像QQ一样可以自动隐藏? 一个关于dll的例子,运行不了,请帮忙看一下。 程序打包 BCB产生调试符号的问题 为什么要4张1寸的,1张2寸的照片?要这么多干什么/ 请问怎么样用C#遍厉注册表? 请问大家如何做一个实时的屏幕抓取的程序啊,是实时 各位大哥大姐帮帮小弟,先谢谢了!!! 用Delphi开发的WebService能否在NT4的IIS上面运行? 键盘纪录问题 一个窗体有多个按钮,怎样让一个按钮成为默认按钮? 关于MYSQL_CONNECT(),有点疑问 ASP.net好像也不能替代JavaScript吧? 网络游戏外挂之我所见(7) 键盘纪录问题 键盘记录问题 我为谁哭泣.. sql小问题 大家快帮帮我吧,我快崩溃了 谁知道VisualAge for Java 3.5的help打不开该怎么办?(能解决问题必给分) 网络游戏外挂之我所见(7) 谁知道VisualAge for Java 3.5的help打不开该怎么办?(能解决问题必给分) Access数据记录复制? 急﹗﹗﹗ 关于数据库表的问题 cpu设计学习的问题 也许是很土的问题 哪位兄弟能帮我VB做的dll转成标准的dll。 充电器上5A 10A 15A He's under the tree.(改为一般疑问句) 三相四线漏电开关能否把3个相线并联后用在单相电中?手头有个3相4线漏电开关,担心用电高峰用单相电流不够,想把3个相线柱子并联,这样是否可以增加单相输出电流?比如额定三相20A的可以变6 在△ABC中,AB=AC,∠BAC=∠108°,当∠CAD=72°时,△ABD与△ACD是等腰三角形吗?为什么?只有ab=ac 不等于cd 请问胶体电池的优点有哪些? 英语200字作业 你如何看待google谷歌公司退出中国大陆市场的原因,影响中美之间在审查制度上的区别如何? Rt△ABC中角BAC=90°,AB=AC=2,以AC为一边,在△ABC外部做等腰三角形ACD,则BD=? 要是想要使用10A的熔丝 但手头只有15A和5A的熔丝 怎么办?(两条方案)想不通如果是两条5A串联 那么只要电流过了5A不是两条都熔断了么.等于没效果啊 = = 碳排放交易市场怎样申请 10a乘10a等于 什么是胶体电池 生活在距今约180多万年前的()西侯度猿人已经有了简单原始的渔猎生活.白天不懂夜的29452 (5a方b方+10a方b的立方)除以多少等于a+2b 几十年前,我只有十来岁,还在贫困的农村,那时候还不知道香蕉为何物.一次他母亲带他去参加在县城远方亲戚的婚礼.在宴会上,他平生第一次见到了香蕉,黄灿灿的,月亮一样的形状,透着诱人的 如何切入碳交易市场 为什么要倒置培养 小儿7个月了,打算一天让他吃半根香蕉,有人说香蕉凉性不能吃,易拉肚,请专家指点.自己觉得香蕉是个好水果,可以补充钙吧,所以想让孩子每天吃香蕉.现在7个月了还没长牙,又不想让吃买的钙 半圆的周长怎么求 -5a的3次方+10a的2次方-20a 等于多少 将两颗相同的种子种在一片肥沃的土地上和一片贫疾的土地上那个先发芽?为什么理由 三角形边长分别为33米,19米,24米.求面积 想去天空之镜—玻利维亚乌尤尼盐沼要会什么语言么 高电压、低电压是怎么划分的啊 三角形边长分别是42米、44米、24米求面积因是面积补偿争议 玻利维亚 乌尤尼盐沼 挺说玻利维亚 乌尤尼盐沼 下完雨之后的景色是最美的我想问问 那里常下雨吗如果去 什么季节去最合适 北京有去乌尤尼盐沼的旅行社吗? 如图 AB是半圆的直径 直线MN切半圆于C,AM⊥MN BN⊥MN 如果AM=a BN=b 那么半圆直径是多少? 英语翻译:“琐碎的事情”有没有一个词代表“琐碎的事情”呢?用在iBT口语中. 初二一次函数:根据图象回答问题1.A、B点分别代表什么?2.说一说这两个数量是怎样变化的? AB是半圆的直径.直线MN切半圆于点C,AM⊥MN,BM⊥MN,若MA=4,NB=3,求直径AB的长 英语中一些琐碎的问题有时候对英语感觉很无语,例如吧:bit的现在分词我觉得应双写t加ing,但他就非要是biting.做题中遇到要填一个词“noise levels”但我觉得level不需要加s啊?再例如,no后跟单 聚集蛋白是什么意思 直线MN切半圆于P,AB为O的直径,AM⊥MN于M,BN⊥MN,若AM=a,BN=b,则AB的长为?梯形AMBN的面积为? 问几个琐碎的英语问题、1、情感(名词)用英语怎么写、是可数的吗?2、翻译一个句子、它不但是感情而且是行动.(用not only...but also)3、“快乐大本营”用英语怎么翻译或者是无法翻译?4 √10a·√5a=5√2a这道题对吗还有 a√1/a=√(a²·1/a)=√a 这个对吗 青海湖的含盐量算什么湖?如题 什麼是水压 细胞真的在晚上繁殖? .tar.bz2的解包问题我在linux中用tar -xvf没法打开用tar -xjvf 可以打开请问 -xjvf 琐碎的事 用英语怎么讲 用15牛的水平拉力在水平面上拉A物体,A物体做匀速直线运动,若改用20牛的水平拉力拉A物体,则A物体做( )运动,此时A物体受到的摩擦力为( ) 过半圆O上的一点C作直径AB的垂线,垂足为D,圆O1切AB于点E,切CD于点F,内切半圆于G.求证:AC=AEG在BC弧上 琐碎翻译成英文 5a-1/8=7/4 半圆的直径为40与半圆内切的动圆与直径AB切与M设动圆半径为yAM长为x求解析式 已知三角形ABC三条边长分别是18,24,30则最长边上的中线是多少 三名同学量体重,小影,小佳俩人的平均体重是43千克,加上小明的体重后,他们三人的平均体重就增加了2千克.小明的体重是多少 青海湖的美,美在湖水蓝,令人醉 仿写 写出四位中国奥运会冠军和他(她)从事的项目 a big mess 的意思 青海湖的湖水有什么特点?为什么会有这样的特点呢? 电池组:关于电池组 12V 20AH与24V 20AH,两个都是输出2.0A电流,容量是否一样?功率如何计算? I’ll clean up my mess when I’ve buried him.my mess在这里是什么意思呢? 我叫徐建蕾 想给自己取个英文名 希望大家帮我取一个好听点的英文名 我有一个48V20A的直流电瓶,怎么转换成220V交流电,具体需要什么元件?市场是否好买? 蛋生鸡先?蛋生鸡还是鸡生蛋先? 青海湖、湖水面积有多少平方米 我一会儿出去用英语怎么说i am gong out _____ _____ 我把CAD图平面图放进去我要怎么算比例尺呢 我叫兮希望大家帮我取个好听点的英文名要加读音备注哦 高一物理问题A.B两质点从同一点开始沿直线运动,右图中的①、②分别为二者的υ-t图线,则下列判断中正确的 巴基斯坦奎达发生爆炸4人死亡土耳其总理要求国际社会帮助解决叙利亚津巴布韦灵车与油罐车相撞20人死亡许其亮与俄罗斯国防部长举行会谈卫计委:非诊治需要不得对儿童开展微量普京被评为全球最有影响力人物 奥巴马马凯会见爱尔兰总理肯尼中国公司赞助安哥拉发展乒乓球运动浙江武义江遭企业偷排 PH值、化学需俄驳日媒报道 称不会与日讨论中国“潜刘云山:确保教育实践活动善始善终、善中央第九巡视组进驻三峡集团开展巡视工国信办主任鲁炜:网聚正能量 共筑中国保加利亚查获大宗贩毒案巴基斯坦西南部发生爆炸袭击 造成至少全球十佳旅游城市排名揭晓 上海第六巴日美拟明年将普天间空中加油机转往岩国中国“北斗”即将在泰国落地使用宁夏“10·14”灭门杀人案犯罪嫌疑中组部:干部离退休3年内不得到原管辖杭州一大妈在城市空地种2000余株罂罗伊斯队长首秀提前被换下 意甲金靴难枪手7分钟2球绝处逢生 连续两场终场对藏品的态度决定藏家的层次文章5王世襄:玩物玩出“京城第一玩家”成龙低调离京 柯震东陷四面楚歌华鼎奖谢绝“毒星”宁财神门前半米空门不进 这事发生在德甲……新疆对8名暴恐犯罪分子执行死刑内马尔又伤了哈默德复出 富力为进亚冠全力出击十大堵城出炉 广深榜上有名弗雷德号召罢赛 无人响应门前半米空门不进 这事发生在德甲……哈默德复出 富力为进亚冠全力出击“铠甲F4”貌美 粉丝求加露脸戏双胞胎男团Tasty 会是你的菜吗?内马尔又伤了国防部:中方敦促美方停止对华抵近侦察企业年报作假 10月起进“黑名单”山西两名省委常委接受调查
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘