常见的 Python 编程错误
这里总结了我多年来进行Python开发所犯的一些错误。虽然算不上一个『权威』列表,但这是我发现我的同事和朋友都常犯的错误类型。如果你觉得还有其他的错误需要补充,请在评论里告诉我!
错误 1# 在遍历的过程中修改列表
Python
>>> li=[1,2,3] >>> for i in li: ... i.append(4)
>>>li=[1,2,3] >>>foriinli: ... i.append(4)
这个有限循环变成了无限循环
错误 2# 错误理解了 Python 变量作用域
当一个变量在函数里被赋值时,Python 会假定它是在本函数内部定义的
Python
>>>i=[1,2,3] >>>def print_i(): … print i [1,2,3] >>>def modify_i(): … i=i+[4,5]
>>>i=[1,2,3] >>>defprint_i(): … printi [1,2,3] >>>defmodify_i(): … i=i+[4,5]
错误 3# 认为 True 和 False 是关键字
在 Python 2.x 版本中,True 和 False 不是关键字,所以
Python
>>>True = False >>>if True == False: … print “end of the world”
>>>True=False >>>ifTrue==False: … print“endoftheworld”
错误 4# Python 2.x 和 Python 3.x 之间的差别
在 Python 2.x 中
Python
>>>print “hello world” hello world
>>>print“helloworld” hello world
在 Python 3.x 中
Python
>>>print “hello world” File “<stdin>”, line 1 print “hello” ^ SyntaxError: invalid syntax >>>print (“hello world”) hello world
>>>print“helloworld” File“<stdin>”,line1 print“hello” ^ SyntaxError:invalidsyntax >>>print(“helloworld”) hello world
错误 5# 数据结构不是不可变对象
Python
>>>li1 = [] >>>li2=li1 >>>li2.append(1) >>>print li1 [1]
>>>li1=[] >>>li2=li1 >>>li2.append(1) >>>printli1 [1]
这是因为我们只创建了一个对象,然后给它绑定了不同的名字。因此当你修改这个对象时,所有指向该对象的变量都会被改变。
错误 6# 在异常处理块中指定了错误的参数
Python
>>>try: … int(“z”) >>>except IndexError, ValueError: … pass
>>>try: … int(“z”) >>>exceptIndexError,ValueError: … pass
这段代码无法正常运行,因为 IndexError 是你要捕获的异常类型,ValueError 是指你要把捕获到的异常赋值给这个变量名
捕获多种异常的正确代码应该是这样:
Python
>>>try: … int(“z”) >>>except (IndexError, ValueError): … pass
>>>try: … int(“z”) >>>except(IndexError,ValueError): … pass
错误 7# is 和 == 操作并不一样
Python
>>> a=257 >>> b=257 >>> a is b False >>> a == b True >>> id(a) 23486712 >>> id(b) 23486736
>>>a=257 >>>b=257 >>>aisb False >>>a==b True >>>id(a) 23486712 >>>id(b) 23486736
is 操作检查两个对象是不是同一个对象,而 == 操作检查两个对象的值是否相等。
错误 8# import 语句只在第一次生效
你可以通过在交互提示符下 import 一个文件来执行它,但在每一次会话中,这个只会生效一次。之后的 import 只是简单的返回一个已经载入的模块。想要强制 Python 重新导入并返回一个文件的代码,可以执行 reload(module)函数。当你想这么做的时候,请确保使用 reload 函数来重新导入,而非再次 import。
错误 9# 整数除法
Python
>>> 5/2 2
>>>5/2 2
你可能想要的是:
Python
>>> 5.0/2 2.5
>>>5.0/2 2.5
除法操作至少要有一个操作数是 float 类型。
错误 10# 没有正确理解类变量
Python
>>> class X(object): … a = 1 … >>> class Y(X): … pass … >>> class Z(X): … pass … >>> print X.a, Y.a, Z.a 1 1 1
>>>classX(object): … a=1 … >>>classY(X): … pass … >>>classZ(X): … pass … >>>printX.a,Y.a,Z.a 111
当 Y 的变量 a 改变时
Python
>>> Y.a = 5 >>> print X.a, Y.a, Z.a 1 5 1
>>>Y.a=5 >>>printX.a,Y.a,Z.a 151
这个结果和我们的预期一样,但是当我们改变 X 的变量 a 时
Python
>>> X.a = 3 >>> print X.a, Y.a, Z.a 3 5 3
>>>X.a=3 >>>printX.a,Y.a,Z.a 353
和字典一样,类变量是在内部处理的,并遵循一种 方法解析顺序(Method Resolution Order ,MRO)。在上述代码中,因为在类 Z 中没有找到该属性,它会去它的基类(在上例中只有 X,尽管 Python 支持多重继承)中搜索。换句话说,Z 不像 X,它没有自己的属性。因此对 Z.a 的引用实际上指向了 X.a。除非正确处理这个地方,否则很容易出问题。