对编程规范的信仰
1.每个语言都有专门和委员会
2.每个语言相应的编程规划群
3.每一个代码提交,都类似于Git里的diff
4.有大量的开发自动化工具。
统一的编程规范为什么重要
1.阅读者的体验——编程者的体验——机器的体验
《8号python增强规范》《Google python风格规范》
http://google.github.io/styleguide/pyguide.html
eg:
# 错误示例
if (a <= 0):
return
elif (a > b):
return
else:
b -= a
# 正确示例
if (transfer_amount <= 0):
raise Exception('...')
elif (transfer_amount > balance):
raise Exception('...')
else:
balance -= transfer_amount
再举一个例子,Google Style 2.2 条规定,Python代码中的import 对象,只能是package或者module
# 错误示例
from mypkg import Obj
from mypkg import my_func
my_func([1, 2, 3])
# 正确示例
import numpy as np
import mypkg
np.array([6, 7, 8])
因为my_func这个名字,如果没有一个package name提供上下文语境,很难推测功能,也很难在debug时根据package name找到可能的问题。
接下来是编程者的体验,我们常常喜欢简化代码,过度简化自己的代码,一个例子,就是盲目地使用python的list comprehension
# 错误示例
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
一定很多人能一口气写出来这么复杂的list comprehension。其实就是一个简单的for loop
# 正确示例
result = []
for x in range(10):
for y in range(5):
if x * y > 10:
result.append((x, y))
机器体验也很重要
先把list和==的使用区别?
# 错误示例
x = 27
y = 27
print(x is y)
x = 721
y = 721
print(x is y)
is是比较内存地址的,那么两个结果应该都是一样的,可是打印出来的结果不同,一个是True,一个false,原因是CPython(python的C实现,把-5到256的整数做成了singleton也就是说,这个区间的数字都会引用一块内存区域)上面的27与下面的27是同一个地址,运行结果为True.
但是-5到256之外的数字,会因为你的重新定义而被重新分配内存,所以两个指向不同的内存,结果也就是False。
避免去用is比较两个python整数的地址。
# 正确示例
x = 27
y = 27
print(x == y)
x = 721
y = 721
print(x == y)
在看一个==在比较值的时候,是否和你想的一样,可以运行一下
# 错误示例
x = MyObject()
print(x == None)
结果是false,因为对于类来讲,==结果取决于它的_eq_方法的具体实现。MyObject的作者可能这样实现
class MyObject(object):
def __eq__(self, other):
if other:
return self.field == other.field
return True
正确的代码风格,当于None比较时,永远使用is:
# 正确示例
x = MyObject()
print(x is None)
is 和==使用更安全,不仅只 有这两点。还有隐式转换
# 错误示例
def pay(name, salary=None):
if not salary:
salary = 11
print(name, "is compensated", salary, "dollars")
如果要调用("Andrew",0),会打印什么呢?“Andrew is compensated 11 dollars”.当明确想要比较对象是否是None时,一定要显式地用is None
# 正确示例
def pay(name, salary=None):
if salary is not None:
salary = 11
print(name, "is compensated", salary, "dollars")