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

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

总结

详解开源游戏开发框架HaxePunk的主要特性 《程序员》杂志休刊通知 2014 TOP50最具价值CTO获奖名单揭晓! TIOBE 2014年12月编程语言排行榜:R和Swift成为年度语言候选者 免费增值应用正在“杀死”游戏开发者? 直接Mark!开源的DevOps开发工具箱 Apache Mesos联合创始人Benjamin Hindman:谈分布式应用现状 直觉不靠谱!使用移动应用分析的七个巧妙方法 屏蔽、挖角与丑闻,Uber的“创收神器”泡沫 蚁视科技发布会:三大产品与四大概念技术 盘点VS2015 预览版的5个新特性 低能的“智能” 你就是明星,第一届IBM RockStar正式启动! Kubernetes:Google分布式容器技术初体验 方法可以复制 AngularJS资源集合 那些年,微信走过的开放之路 从YunOS话阿里移动互联网云生态布局 Mobile First!苹果联合IBM发布10款企业级App iOS8.1.1越狱又惹急苹果!扒一扒黑客与苹果的斗争史! Firefox.html:用HTML重现Firefox UI Qt 5.4正式发布!引入WP,支持HTML5混合开发 2014智能硬件盘点第二弹!这次咱走暖心的 聚合数据资产,推动产业创新——2014中关村大数据日看大数据变现 拥抱开源:微软Windows 10宣布全面支持AllJoyn技术 改变App领域发展!友盟推“数据工场”战略,两款新品亮相 Cloudera正式登陆中国市场:与英特尔携手共助本土企业淘金大数据 Go 1.4正式发布 支持Android开发 【特别提醒】2014中国大数据技术大会门票全面告罄 不接受现场购票 累计4000万美元 Qualcomm在华投资5家公司 支持Android、WatchKit开发,全新RubyMotion 3面世! 快速开发移动医疗App!开源框架mHealhDroid 如何实现使IE的回退按钮disabled 使用C#开发asp.net时对OO的一点不明白 vbscript调用perlscript(第一次写作,跟贴有分,欢迎交流) 怎样获得polyline曲线上点的坐标? MDI窗口如何关闭所有的子窗口? 求server2000下创建一个虚拟目录分配权限限制用户使用大小的API 想用VB制作一个标签打印系统。急! 为什么可用分不增加了? 请问怎样得到表的列数?如何得到某个列的名称? 有做过门禁系统的近来谈谈 谈的热烈的话我还要加分的:) 想做一个负责连数据库的代码模块,但不知道C#中模块的格式、与怎么调用?请赐教! 关于ODBC API中USHORT方式绑定的问题 有办法保证我的asp程序只能在一台指定的服务器上运行吗? 怎样将该段VB的代码传为C#(有关调用winAPI)? 关于Remoting的配置问题,高手帮忙! 关于安装系统的问题? 各位见笑了,对office不熟,在powerpoint里更改了母版并保存过了以后,怎么再改为不用母版? 高分讨教:如何控制用户的行为 高难度问题!!!~~~~~ 打开首页时,弹出另一窗口! 请问这个问题该怎么处理!十万火急!谢谢! 急:一个.Net 写DLL及调DLL的问题,请大家帮忙!(在线等候......可以再加分msn:w.hua@ynmail.com,qq:25857100) 救命啊 查找某个目录下是否有某个文件 邮箱命名的问题??? 怎样在一个窗口控件中显示两条自由报表的记录? 紧急求助USB带宽 请问哪里能下到《inside the c++ object model》英文版啊,谢谢 新手提问,大侠莫抛弃我,谢谢,请往里看。 求教:我想拦截CreateProcess()的调用,并取出参数是否可行???? 这是什么病毒 如何指定发送端口 如何设置treeview的scrollbar? 请问各位,谁写过一个程序的整个文档,小弟很急,想参考一下。不知是否可以。谢谢了! 打算过年后跳槽,大家帮帮忙看看我这水平能拿多少?来者有分 天灾 +人祸100分求救 各位再请看看: ccur(922337203685477.30)=922337203685477.25 ??? 用JAVA做APPLET程序的朋友请进!!! 如何使应用程序(基于对话框)在状态栏里不可见 急,求救!在线等!请帮忙,谢谢 SQL Server 的客户端问题? 在线等; 好好的程序不能运行了 ,提示:不能创建宏 怎样打开一个数据库在单文档的视中显示数据??(我没有没结过的贴) 调用外部程序的问题 偶去吃饭了!大家去吗?我请客好了:) 大家能不能介绍一下四川的迈普 VB6到VB.NET升级问题?有的FORM可以升级,有的不行,错误如下:(急!!!搞定立即散分!在线等!) 男人的花样,女人的年华(淡月儿) 如何在VB中正确将调用的Excel进程关闭? 请问 void UpdateDialogControls()函数怎么用……(******) 英语我不会咋办?请大师指导! _---Which do you think tastes______.---- none.选择good ,better ,best 露台与阳台有什么区别?起居室是哪个房间? 我不会英语咋办 单词能背下来 就是 其他的全不会 什么是CIQ实验室 房子装修厨房,卫生间,阳台做一个高度.客厅,餐厅,走廊,卧室地面都做一样高好还是卧室略低点好?请问风水上对厨卫,厅,卧有什么说法? 如果读英语没效果怎么办 The t( ) of the food is good.I like it. he left the place,____never to come back.A.determined B.determining 请做出详细的讲解. 怎么办那,英语不会做, 英语翻译What should I do next june if i not work hard now We won 't go sightseeing if tomorrow .[A.it rains B.it will rain C.it would rain D.it rained ] 英语高手进.帮我起个英文名.我叫曾雅雯.谁帮我起个比较接近的英文名.谢拉. Live as if you are going to die tomorrow Study as if you will never die! The fish is very d .I like it a lot.The fish is very d .I like it a lot.D后面填什么? 会起英文名字的进我是女生、想请高手帮我起个英文名字.要可爱一点的.因为是走可爱路线的哈、别人都说我是菟宝宝、汗汗、水瓶座的、不要那种很常见的、想要独特一点的、我姓李、最 英语定语从句和宾语从句的关系词我不会用怎么办 CIQ可以做吗?we needs a CIQ test done on the PTA from your company before he will place the order.What is the quickest you can supply me your product’s CIQ by this special government department.This is for exporting the product客户的原文是 英语高手进,帮忙起个英文名欧洛,奥洛.类似中文读音. I have thought it would be an excellent rule to live each day as if we should die tomorrow.的语法 我家阳台一夜之间出现几十只大苍蝇,好像是牛虻墙面上到处都是,特别多,外形像苍蝇,比蜜蜂还大,全赶走后,第二天又会出现,窗户都是关闭的,不知从哪里来的,有点毛骨悚然的感觉. 英语翻译智力题也行! “外籍教师应聘登记表”用英语怎么说 初二上册please speak English more loudly,Miss zhang.I can ( ) hear you.please speak english more loudly,miss zhang,I can ( ) hear you.A .probably B、hard C.hardly D.almost 你认为威海的天气怎么样?用英语怎么说? 给我一些小学英语的重点的知识,特急! 小学英语应掌握的要点是什么?具体一些, “中国工商银行山东省临沂市兰山区支行”用英语怎么说谁能告诉我“中国工商银行山东省临沂市兰山区支行”如何翻译成英语急切知道 致命访客英语怎么说 求小学英语最简单要点,如过去式我是个小学生…请大家说简单一点的.比如:where when do who 是什么句型开头.ed是什么等等等等. bad 的反义词是啥? 顺便来访用英语怎么说 我的理想是军人,现在我该怎么做作文 英语, 我很盼望下周日你的来访用英语怎么说 内置阳台装修效果图 户外阳台装修效果图 最新阳台装修效果图 英语不会做,帮下忙, 晚上来访请走正门 用英语怎么说?在线等 请各位达人帮帮忙,谢过了. ___(do) your teacher like __(speak) English? 不会英语咋办 The fish has got burnt.It tastes too____to eat.A badlyB bad C goodD well 有谁知道这首英文歌曲叫什么?或是能听出里面那句一直重复的歌词是什么?我英文比较差劲哈http://www.446655.com/Play/youmeidexuanlv3330.html 不会英语怎么办 My physics teacher is very humorous.One day,he told speak English very well.My physics teacher is very humorous.One day,he t___us that he could s___ English very well.We were all surprised to h________ that,since he was n___70 years old!He also told 是用 look out of the door 还是look out from the door 帮我起个英文名字,我的名字叫(常浩然),英语达人们说说看我的英文名字应该叫什么.财富值全都给你了,有劳大神费费心.请大家说说你们给我起的名字的意思,或者说你们为什么给我起这个名 找出错误,并改正:My English teacher can(A) play(B) piano(C) very well.( )_____哪个错了?A、B or All of a sudden,the door shut等于什么 哪里有小学英语的基础知识? live as though you were to die tomorrow的下句是什么,它们的意思是什么 有谁知道这首英文歌曲的?有没有人知道这首英文歌的,歌词中有“.the bad girl”,是女生唱的,貌似是欧美的,是首劲歌,有谁知道这首歌曲名字的?歌名里也有《...the bad girl》 walk的现在分词 怎么办呢?英语不会啊 All of ____ sudden,we saw a boy rush out of ___ nack door. A a;a B a;the C the;the D the;a 求解析是back door nice的反义词是什么? 小学英语语法要注意什么例如什么LIKE后加ING之类的…… 我是大连的想考公共英语三级 谁知道有没有保过的 准点的啊 nice的反义词 l can speak english,l also apeak french.l can speak english and french_ _ 锦州市公共英语三级有保过吗
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘