你忽略了哪些PEP 8指南,哪些又坚持?
随着我写Python的时间越来越长,我发现自己越来越认同大部分的编程规范,尽管我还是会出于自己的原因故意违反一些规则。
我很好奇大家在PEP 8(或者其他PEP)中,哪些地方是大家非常坚持的,为什么会这样?又有哪些地方让大家觉得不方便或者不够好。
就我个人而言(还有我工作的地方),我们偏离的地方其实不多:
关于用下划线分隔的小写名字,我能理解这样做的好处,因为这样会保持一致性,但我们通常使用小驼峰命名法(lowerCamelCase),虽然这样偶尔会导致一些不一致(比如部分或错误的大写缩写和后面的单词,这往往是临时决定的结果)。主要是因为我们常用的API几乎都是用驼峰命名法(有些是大写,有些是小写),而且我觉得这样更容易阅读,通常会把下划线留作分隔符或者特定的混淆用途。
我还是无法按照PEP的要求在对象内部留空格。比如,new和init我通常会放在类下面,不留空行,因为我总想和类名、参数一起看到它们。属于同一功能范围的方法(比如init、get和set同一个属性或一组属性)我只留一个空行,而类之间我喜欢留三个空行,方法之间留两个空行,这样我在脑海中不会把它们混在一起。这些都是为了代码的视觉效果和可读性。我发现,控制流内部的内容很紧凑,以及方法和对象之间的这种空格,能让我在几个月后重新阅读代码时,眼睛能准确找到我想看的地方。这也很适合我喜欢的编辑器的折叠功能。
有些地方我还是会坚持,比如用制表符而不是空格(尤其是我们用的一些应用内编辑器并没有真正的制表符替换功能,这在原型阶段会严重污染代码库)。
像导入的顺序、导入的内容、全局变量等。这些东西如果混在一起或者顺序错了,我在看文件时会觉得很困扰,尤其是当导入的内容很多的时候。
语句中的空格,特别是当有人用制表符并试图在不同长度的变量名之间对齐赋值操作时(而且似乎没有办法说服那些这样做的人,代码看起来像Excel的样子并不整洁;)
还有控制块内部的空格,尤其是当我看到同一个控制流块内的空格看起来很随机时,以及在对象内部的方法中使用类似的空格。我总是忍不住想先修改这些,才能开始阅读代码。
这就是我的一些看法,以及我“违反”PEP的原因(有些是大家都认可的,有些则是同事们不太赞同的)。我很想知道其他Python爱好者在这些方面是怎么做的,哪些是坚持的,哪些是放弃的。
14 个回答
PEP8 说:
最重要的是,多行文档字符串结束的 """ 应该单独占一行,并且最好前面有一个空行,例如:
"""Return a foobang Optional plotz says to frobnicate the bizbaz first. """
我觉得这个要求有点奇怪,因为这只是“多余的空白”,而且开头的引号和结尾的引号处理得不一样,理由也不太明显。
在 PEP 257 中给出了一个解释:
BDFL(大元首)建议在多行文档字符串的最后一段和结束引号之间插入一个空行,并把结束引号放在单独的一行上。这样,Emacs 的填充段落命令就可以使用了。
Emacs,真的?难道每个人都要为了某个特定编辑工具的奇怪命令而做一些奇怪的事情吗?
我还觉得,把文档字符串的开头放在引号同一行上(虽然不是必须,但推荐这样做),而要求结束引号单独一行,这也很奇怪。我认为这样做更合理,应该对单行和多行文档字符串都适用:
def foobang(bizbaz, plotz=None):
"""
Return a foobang
Optional plotz says to frobnicate the bizbaz first.
"""
if plotz is not None:
...
更新: 之前的要求被删掉了,现在只说“结束引号要单独一行”,而且“摘要行可以和开头引号在同一行,也可以在下一行”。
关于“每行79个字符”的说法真是没啥意义。他们自己举的例子就说明了,代码变得多么难以阅读:
class Rectangle(Blob):
def __init__(self, width, height,
color='black', emphasis=None, highlight=0):
if width == 0 and height == 0 and \
color == 'red' and emphasis == 'strong' or \
highlight > 100:
raise ValueError("sorry, you lose")
if width == 0 and height == 0 and (color == 'red' or
emphasis is None):
raise ValueError("I don't think so -- values are %s, %s" %
(width, height))
Blob.__init__(self, width, height,
color, emphasis, highlight)
这就像试着读一篇
像这样写的
新闻文章。
80列的终端环境已经有十多年没被当作真正的开发环境了。当我不得不在一个受限的80x25环境中编辑代码时,编辑器的换行只是个小麻烦;我可不会为了避免这个小问题而在正常开发中把我的代码搞得乱七八糟。
对于现代开发来说,120列的换行是完全合理的,我甚至觉得140列也没问题。这个指导原则已经过时,遵循它只会导致代码难看且难以阅读。
PEP8 说在赋值(或其他)运算符周围不要使用“多个空格来对齐其他内容”,而且在数学运算符周围“永远不要使用超过一个空格”,但我并不太遵循这个规则。
我经常在相邻的行之间添加“多余的空白”,当这些行是相关的或非常相似,但又不完全相同时:
search_start = (f - f_1/3) * n/fs
search_stop = (f + f_1/3) * n/fs
b_lpf, a_lpf = filter(N, 2*pi*fc, 'low', analog=True)
b_hpf, a_hpf = filter(N, 2*pi*fc, 'high', analog=True)
p[x > 1] = np.cosh(order * np.arccosh( x[x > 1]))
p[x < -1] = (1 - 2 * (order % 2)) * np.cosh(order * np.arccosh(-x[x < -1]))
b0 = (1 + cos(w0))/2
b1 = -(1 + cos(w0))
同样,我觉得很烦的是,我在格式化数字数组时会收到 代码风格警告,而这种格式是库本身通常使用的可读格式:
a = array([[-0.198, 0.248, -1.17 , -0.629, 1.378],
[-1.315, 0.947, -0.736, -1.388, 0.389],
[ 0.241, -0.98 , 0.535, 0.951, 1.143],
[-0.601, 1.286, -0.947, 0.037, -0.864],
[ 0.178, -0.289, -1.037, -1.453, -0.369]])
这会产生一堆 E201 E202 E222 的违规警告。
显然,PEP8 更希望它被格式化成这样,因为我们“永远不能”在逗号前或括号后有多余的空白,即使这样会提高可读性:
a = array([[-0.198, 0.248, -1.17, -0.629, 1.378],
[-1.315, 0.947, -0.736, -1.388, 0.389],
[0.241, -0.98, 0.535, 0.951, 1.143],
[-0.601, 1.286, -0.947, 0.037, -0.864],
[0.178, -0.289, -1.037, -1.453, -0.369]])
(而且 Black 的要求更严格:)
a = array(
[
[-0.198, 0.248, -1.17, -0.629, 1.378],
[-1.315, 0.947, -0.736, -1.388, 0.389],
[0.241, -0.98, 0.535, 0.951, 1.143],
[-0.601, 1.286, -0.947, 0.037, -0.864],
[0.178, -0.289, -1.037, -1.453, -0.369],
]
)