不要使用索引来遍历序列。
不要:
for i in range(len(tab)) :
print tab[i]
做:
for elem in tab :
print elem
For会为大多数迭代操作自动化。
如果你确实需要索引和元素,使用enumerate
。
for i, elem in enumerate(tab):
print i, elem
使用"=="检查是否等于True或False时要小心
if (var == True) :
if (var != True) :
if (var == False) :
if (var == None) :
if var :
if not var :
if var is True :
if var is False :
if var is None :
不要检查是否可以,直接去做并处理错误
Python 程序员通常说“宁愿请求后谅解,也不要事先获得许可”。
不要:
if os.path.isfile(file_path) :
file = open(file_path)
else :
# do something
做:
try :
file = open(file_path)
except OSError as e:
甚至更好的是使用Python 2.6+ / 3:
with open(file_path) as file :
这种写法更好,因为它更加通用。你可以在几乎任何情况下都使用"try/except"。你不需要考虑如何预防错误的发生,只需要关注你可能会遇到的错误。
不要检查类型
Python是动态类型语言,因此检查类型会使你失去灵活性。相反,通过检查行为来使用鸭子类型。比如,在函数中需要一个字符串,那么使用str()将任何对象转换为字符串;需要一个列表,则使用list()将任何可迭代对象转换为列表。
不要:
def foo(name) :
if isinstance(name, str) :
print name.lower()
def bar(listing) :
if isinstance(listing, list) :
listing.extend((1, 2, 3))
return ", ".join(listing)
做:
def foo(name) :
print str(name).lower()
def bar(listing) :
l = list(listing)
l.extend((1, 2, 3))
return ", ".join(l)
使用最后一种方法,foo将接受任何对象。bar将接受字符串、元组、集合、列表等等。DRY很实惠 :-)
不要混用空格和制表符
千万不要这么做。你会哭的。
将object用作第一个父类
这有点棘手,但随着程序的增长,它会咬你一口。Python 2.x中有旧的和新的类。旧的类,恩,太老了。它们缺少一些功能,并且可能在继承方面行为笨拙。为了可用,任何你的类都必须是“新式”的。为此,请让它从“object”继承:
不要:
class Father :
pass
class Child(Father) :
pass
做:
class Father(object) :
pass
class Child(Father) :
pass
在Python 3.x中,所有类都是新式类,所以你可以声明class Father:
没问题。
不要在__init__
方法之外初始化类属性
来自其他语言的人可能会觉得这很诱人,因为在Java或PHP中就是这么做的。你写出类名,然后列出属性并给它们一个默认值。在Python中似乎可以正常工作,但实际上并非如此。
这样做会设置类属性(静态属性),当你尝试获取对象属性时,它会返回它的值,除非它为空。在那种情况下,它将返回类属性。
这意味着两个巨大的危险:
- 如果更改了类属性,则初始值也会更改。
- 如果将可变对象设置为默认值,则会在多个实例之间共享同一对象。
除非需要静态属性,否则不要这样做:
class Car(object):
color = "red"
wheels = [wheel(), Wheel(), Wheel(), Wheel()]
做:
class Car(object):
def __init__(self):
self.color = "red"
self.wheels = [wheel(), Wheel(), Wheel(), Wheel()]
range()
作为列表。在Python 3.x中,应该使用list(range())
来代替,可以使用2to3脚本进行转换。请注意,翻译后的内容仍然保留原意,同时更加易于理解,没有解释和额外的内容。 - jfs