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

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)
在程序的正常终止的前提下,这个实现提供了一个整洁可靠的方式调用任何需要清理的功能。

总结

华为应用市场助力开发者 软硬结合造就强大生态系统 【CTO俱乐部看板研修班北京站现场速递】看板方法:渐进变革的过程 《近匠》不背单词,用“沉浸”征服英语学习 ETpl——强复用、灵活、高性能的JavaScript模板引擎 MDCC 2014大会日程概览发布 最新嘉宾议题揭秘 终于来了,微信企业号正式开启公测! 【问底】王帅:深入PHP内核(一)——弱类型变量原理探究 谷歌Kubernetes专访:未来BigTable开发只是课后习题 首届“最具价值CTO”评选来啦!我们在找你! 【CTO俱乐部走进顺丰总部】活动图文直播进行中 中国第一个云主机评测发布:天翼云性价比第一、青云质量第一 Ruby 2.1.3发布,降低内存消耗、修复众多Bug! OpenHW2014开源硬件总决赛鏖战西安 AMD力推异构计算 《坦克世界:闪电战》:PC转手游,不止免费! 【讲师】道里云毛文波:网络虚拟化与SDN实现Docker连通 性能测试:SequoiaDB vs. MongoDB vs. Cassandra vs. HBase 华云数据推运营型PaaS Plus平台,联合Tmax走出“去IOE”的云化之路 聚焦移动新势力 MDCC 2014免费展位团队名单公布 详解Google Authenticator工作原理 云计算的乐高玩具,Docker从根本上改变应用程序开发 【先锋】eSage缔造异构虚拟化管理技术,做数据中心核心思想执行者 Uplinq2014:亲身体验Vuforia与智能眼镜设备 MDCC 2014 移动开发者大会议程全面揭晓! 顺丰模式:物流行业“互联网化”的科技之路 移动应用云服务工具APICloud宣布完美适配iPhone6 从应用分发到能力开放 华为开发者联盟沙龙上的共赢理念 SOOMLA框架:移动游戏分分钟创建个虚拟商店 Facebook:如何让应用适合所有系统、带宽以及屏幕 Docker实践者不能错过2014 Container技术大会的九大理由!(讲师议题全面揭晓) 2014全球云计算大会中国站(CC China)精彩集锦 腾讯X5浏览服务正式开放 30多款APP成为首批受益者 QQ密码存放在哪? ADO的Query控件 能告诉怎样实现2000服务器的电话回拨吗~~ 初级问题之三,关于DataWindow Error 灌水乐园???? 100分答谢高手!-------谁有写代理服务器的经验呢? 帮一下我好么? 救命!!pb6.5是不是不支持oracle的blob类型???? 去掉引导信息??? 为什么我用MFC写的单文档程序在别人的没装VC++的机子上不能运行? 用户登录是密码存放在哪个文件夹里? (简单问题) 请问这个程序为什么抛出这样一个违例??? 问题一个,请教! 增值合订本出的我心不甘 我又来提问了~前天复习是发现一道很怪异的题目~ 用activemovie控件打开一个URL,用哪个函数? 如何去掉ACTIVE MOIVE控件下面显示的几个键和进度条 c源程序。 >>>>高分求解!!!我在一个对话框中插入一个active report run time design,但程序运行时却不显示,在vb中却可以,如何解决这个问题?????? 关于sql server的安装 哪里有下载cc编译器的? 关于导出数据窗口数据的问题,明白人请进! delphi可不可以用于自动控制方面的开发呢 如何使对话框程序执行就让整个屏幕背景变黑色?? 想了解有关程序考试的一些情况? 不同系统就不可以直接电缆直接吗? 怎样使用PQMAGIC对硬盘进行调整分区 memory fault--core dumped的问题 有谁知道怎么解win98的开机密码? 用 procedure 与 trigger 、database link 能完成吗? flowerofwind,rjcludy()请回答 COM中的一个怪问题:我将::CoUninitialize();去掉后程序不出错,添上出现非法操作,是啥问题??? 请问?????? 如何在程序中播放rm格式的文件??? edit怎么用啊? JB6盘中不含 Borland Enterprise Server AppServer5.0,各位快载一个上去吧! 如何改变显示的分辨率? 那里有c#编译器免费下载?谢谢 如何在vc中播放rm格式的文件??? 那位大侠知道怎么创建并使用一个变量,每次只让一个进程访问???给个例子吧,大大大 大 delphi中怎么编写中断,获取外部设备传来的信息?急救!! 数值模拟与计算仿真,高手请帮忙! 请问:dos下图形放大算法或思路?还有.........(高手请进) 求教!!!!SOS!! --请问如何将一个BMP图形文件转成JPG图形文件,高分请教师--- 高分给出,win98的怪问题! 打印统计问题 请教 : html的javascript 中报错:document.Form1.client_name.value不是对象 VC++里面如何从文本文件中一行一行读取文件? 请问,如何用mail函数批量发送邮件.多谢. 各位请教一下,Jsp 的服务resin在win2000下是怎样配置的 各位兄弟: 有谁知道 侯杰 的 <多线程程序设计> 什么时候才能买到??? 哪里有VFP3.0下载? 在容积相同的两密闭容器A和B,保持温度为150度,同时向A容器中加入amol的HI,向B容器中加入bmol的HI a大于b当反应达到平衡后,谁用的时间长 为什么 氟锑酸的ph值是多少 有HFO 次氟酸的存在吗? 已知函数f(x)=1+(x绝对值-x)/2 1,用分段函数的形式表示该函数.2,函数的值域 画出函数y=x^+(2绝对值)+3的图像 57. 在很长一个时期,人们一直认为氟的含氧酸不存在.1971年美国科学家通过细冰获得次氟酸(HFO),对次氟酸德研究引起充分重视.试回答下列问题:(1) 次氟酸的电子式为_______(2) HFO中各 已知函数f x等于x减一的绝对值,用分段函数的形式表示该函数. 一支温度计的刻度均匀但不准确,将它放入冰水混合物中,示数为4摄氏度,放在1标准大气压下的沸水中示数为94摄氏度.现放在教室里,示数为25摄氏度,那么教室里的实际温度是多少摄氏度 在二次函数中 b的绝对值和c的绝对值怎么比错了错了 是a b的绝对值 钨、铜的熔点分别是3410℃、1084.5℃,估算最低再结晶温度,并选择再结晶退火温度 已知函数f(x)=绝对值x-1 -绝对值x+2 用分段函数表示 一支温度计的刻度均匀但不准确,将它放在冰水混合物中,示数是4℃,将它放在一标准大气压的沸水中,示数是96℃,如果用温度计去测得室温为18℃,那么该室内的实际温度为多少度? 氟气和氯气是什么颜色的?氟气和氯气是什么颜色? 非晶体的熔点融化时的变化 氟锑酸怎么装?我一直想,玻璃,石英什么的,忘了聚四氟乙烯了 氟气是什吗颜色啊 非晶体到底有没有熔点? y=x+1的绝对值的函数图象 F2(氟气)有颜色不?如果有是什么颜色呢? 油酸甘油酯氢化方程式.牛人进 描述实验中水在沸腾前和沸腾时的情景水中气泡在沸腾前( ),沸腾时( ).水的声音在沸腾前( ),沸腾时( ).请问:水的声音在沸腾前和沸腾时发出怎样的声音? 氟气有什么气味?就是氟气有什么味道 油酸甘油酯和氢气加成的化学反应方程式? 氦合氢离子和氟锑酸哪个酸性更强 金会和活泼的氟气反应吗 油酸甘油酯的硬化方程式要准确的!、、 氟锑酸是固体吗 “晶体有固定的熔化温度,非晶体只要吸热温度就会不断上升没有确定的熔点”这句话对不对? 函数y=x的绝对值+1的图像y=x+1的绝对值的图像与y=x+1的图像的关系 画出函数f(X)=1-x2的绝对值/1+x的图像,并写出这个函数的单调区间 非晶体没有一定的熔点,就是说它熔化除了温度还有别的因素了?我有两个想法:1,非晶体熔化,除了温度以外还与比如形状,质量之类的有关,以至于每次熔化的温度都不太相同.如果是这样的话, 硬脂酸甘油酯碱性水解方程式 氟锑磺酸和氟锑酸的区别好像都是HF和SbF5的混合物吧. 晶体有固定熔点是什么意思?指的是一开始融化的温度吗?非晶体没有固定熔点这句话怎么理解?能举个例子吗?还有图中的两个图像又该怎么理解?甲图像中的A处就是熔点吗?ABCD又分别指的是什 硬脂酸甘油酯 碱性水解方程式 画那些自变量外有绝对值的图像,是先画绝对值还是先平移,为什么? 装氟气的集气瓶怎么这么奇怪这是装氟气的集气瓶.怎么集气瓶口上还有一个圆形的东西(淡黄色的),但是装其他气体的集气瓶都很正常 谁告诉我是怎么回事? 硬脂酸甘油酯在酸、碱环境下水解方程式最好可以手写传图! 含绝对值的函数图像怎么变呢?比如,y=|x|-3 和 y=|x-3|的图像有什么不同呢?该如何变? 低温或常温下氟气为什麽可以装在合金瓶quick!please! 函数y=x的绝对值分之2的图像大致是什么样的.为什么. F2+H2O=HF+OF2该反应用等号还是可逆号? 在一定体积的容器中,加入I.5mol氙气和7.5mol氟气,于400摄氏度和2633kPa条件下加热数小时,然后迅速冷却到摄氏度,容器内处得一种无色晶体外,还余下4.5mol氟气,则所得无色晶体产物中,氙原子与氟 画出函数图像:y=x²-2,x∈Z,且x的绝对值≤2 在(3)BrF3+(5)H2O=HBrO3+Br2+(9)HF+O2↑的反映中.当有3molBrF3参加反应时,其中被水还原的BrF3的物质的量是?A.1mol.B.4/3mol.C.2mol.D.3mol.为什么答案会是B呢? 氙和氟按一定比例混合,在一定条件下,可直接反应并达到平衡:Xe(气)+2F2===XeF4(气)+Q下列变化中既能加快反应速率又能使平衡向正反应方向移动的是:()A加压 B升温 C减压 D降温为什么B 制取二氧化碳的方程式 为什么f2与naoh有两个反映:F2+4OH-==2F-+O2+2H2O 2F2+2NaOH=OF2+2NaF+H2O 求化学. 取1摩尔氙气和3.5摩尔氟气于一密闭容器充分反应,后余下1.5摩尔氟气,同时生求化学. 取1摩尔氙气和3.5摩尔氟气于一密闭容器充分反应,后余下1.5摩尔氟气,同时生成白色固体,此白色 制取CO2的方程式 在“观察在水的沸腾”的实验中 氙与氟气反应生成什么 画出函数图象:y=绝对值x+1加绝对值x+2 请问 “AgF+Cl2+H2O= AgCl+AgClO3+HF+O2” 怎么配平呢快啊 函数f(x)=x^2-|x+a|为偶函数,求a的值.解开绝对值 已知关于X的函数y=(m+2)x^m的绝对值-1是正比例函数,(1)求m的值;(2)画出函数图象. 在HFO(次氟酸,HOF)中F显-1价,可以看作F的最高价态了,那么HFO和HClO4的酸性哪个更强?能按递变性解释 设|a|≤1,函数f(x)=ax^2+x-a,x∈[-1,1].证明|f(x)| 人碰到一点点氟锑酸会怎样?有什么可以来中和救人不? HFO(次氟酸)中的O真是0价么?据化学说上说只有单质为0价.如果O为0价,那么不就放出去了么?他们是怎么结合形成的,F在化合物中(有机或无机)会出现正价么
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn