您忽略了哪些PEP 8指南,以及您坚持哪些?

41 python pep8 pep

多年来,我写的Python越多,我就越发现自己同意大多数指导方针,尽管我一直并故意为了自己的原因打破了一些.

我很想知道PEP 8(或其他PEP也可能)人们虔诚地坚持和为什么,以及人们发现不方便或不足的内容.

在我的情况下(以及一般的工作),我们只有少数几个偏离的东西:

  • 下划线小写名称,我可以看到它的重点,因为它将始终保持一致,但我们倾向于使用lowerCamelCase,即使它偶尔会引入一些不一致性(例如部分或错误大写的首字母缩略词和跟随的词,这是经常下降到一时冲动的电话).主要是因为我们经常使用的近乎全部的API使用camelCase(一些较高,一些较低),并且由于某种原因我发现它更容易阅读,并且倾向于将下划线保留为分离令牌或规定的修改/模糊.

  • 我仍然无法让自己按照PEP规定的内容来解决问题.new和init我倾向于在类下面没有空行,因为我总是希望用类名和args读取它们,这些方法有助于类中相同的功能范围(比如init,get和set)同一个attrib或一组attribs)我只分开单个空格,我喜欢类之间的三个空格,两个方法之间我不会在该对象的地图中进行心理聚合.这再次纯粹是为了代码的视觉冲击和可读性.我发现流量控制中的内容非常紧凑,方法和物体之间的这种间距一直引起我的注意,我希望它在代码停放几个月后重新读取.

  • 有些事情反而是我坚持,当我阅读其他文字时,这让我疯狂,是标签而不是空格(特别是当我们使用的一些应用程序内编辑器没有真正具有标签替换功能时,对代码库中的污染造成很大影响)原型设计阶段).

  • 诸如导入之类的东西的顺序,以及什么是导入,全局变换等等.当这些文件混合或乱序时,它真的会抛弃那些具有大量导入的文件.

  • 语句中的空格,特别是当人们使用制表符并尝试在var名称中跨越不同长度的行对齐赋值操作时(并且似乎没有办法说服那些做excel看起来代码片段的人不整齐;)) .

  • 并且在控制块内的间距,特别是当我在同一流控制块内看到明显随机的间距,然后在对象内使用类似的间距用于方法时.在我开始读这该死的东西之前,我不得不编辑那些.

所以,那些是我的,以及我"违反"PEP背后的原因(有些是共享的,有些是同事不赞同的).我很想知道其他Pythonistas在这方面做了什么和不做什么.

Gle*_*ard 50

"每行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)
Run Code Online (Sandbox Code Playgroud)

这就像试戴
ING阅读
新闻arti-
书面CLE
这样.

十多年来,80列终端并不是一个严肃的开发环境.当我确实需要在瘫痪的80x25环境中进行编辑时,编辑器包装是一个小小的不便; 为了避免这种情况,我不会在正常开发期间破坏我的代码.

120列包装对于现代开发是完全合理的,我对140没有任何问题.该指南已经过时,并且会导致难以读取的难以阅读的代码.

  • 每行79个字符可以很容易地将两页代码放到1680px宽屏幕上.该代码也可以更好地格式化; 这是一个反对79个字符线的稻草人. (42认同)
  • @Nick:我不会屠杀我的代码以适应你奇怪的窗口安排.这个代码在包装*时直接从PEP-8部分复制*,因此将它称为"稻草人"是非常荒谬的. (38认同)
  • 我最初真的反对80个字符的东西,但是我发现如果你在一组括号中包含像这个示例中的条件部分,并使用lisp样式的缩进,它可以很好地工作.如果仍然不可能,我将其视为我在一行中做得太多的一个标志,并创建一个中间变量赋值或函数来处理部分复杂性.我实际上忘了可以用反冲来逃避换行:我从来没有这样做过. (32认同)
  • 一般来说,如果你在一行中有超过79个字符,那么你在那里做的不止一件事,无论如何都应该将其分解为可读性.仍然,正确的描述性名称意味着有时您的线条将超出限制,这很好.实用性胜过纯洁. (10认同)
  • 这段代码是79列是*good*规则的完美示例,有更好的方法来实现相同的逻辑.通常超过79列是设计不佳的标志. (9认同)
  • @GlennMaynard IMO,Python最大的两个优势是可读性和一致性.如果你的线条经常变为> 79个字符,那么你就会对它产生负面影响.这样做有理由超过负面 - 比如描述性变量名称 - 但它们是例外,而不是规则.你有一个110-120代码的例子,你觉得应该是一行吗? (3认同)
  • @LyndsySimon:不,事实并非如此.编写良好,完全自然且可读的代码通常扩展到110-120个字符. (2认同)
  • 我的桌面屏幕上只能容纳90个字符(列)的代码.我在笔记本电脑上使用没有侧边栏适合70.这是由于视力不佳.不是每个人都可以拥有120个字符的宽屏幕(我的桌面是32英寸,但我的视力没有变得更好).此外,downvote是因为你的"例子"甚至不符合PEP-8.如果你要去抱怨它,并发布一个例子,发布一个合规的例子. (2认同)
  • 将代码包装在 80 列会导致代码不可读,因此您的 -1 有点有趣。 (2认同)

end*_*ith 44

PEP8表示要避免"在赋值(或其他)操作符周围有多个空格将它与另一个操作符对齐"并且"从不使用多个空格"围绕数学运算符,但我不遵循这一点.

当相邻行相关或非常相似时,我经常添加"无关的空白",但不完全相同:

search_start = (f - f_1/3) * n/fs
search_stop  = (f + f_1/3) * n/fs
Run Code Online (Sandbox Code Playgroud)

 

b_lpf, a_lpf = filter(N, 2*pi*fc, 'low',  analog=True)
b_hpf, a_hpf = filter(N, 2*pi*fc, 'high', analog=True)
Run Code Online (Sandbox Code Playgroud)

 

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]))
Run Code Online (Sandbox Code Playgroud)

 

b0 =  (1 + cos(w0))/2
b1 = -(1 + cos(w0))
Run Code Online (Sandbox Code Playgroud)

同样,令人讨厌的是,我获得了数字数组的代码样式警告,这些数字以可读方式格式化,通常由库本身格式化:

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]])
Run Code Online (Sandbox Code Playgroud)

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]])
Run Code Online (Sandbox Code Playgroud)

  • @ThE_JacO:我会说这个*通过将它们放在一起来突出显示差异,就像diff工具一样.如果它们没有对齐,您可能会注意到一个区别而另一个区别. (44认同)
  • 当目标是更好的可读性时,这让我感到疯狂,这违反了规则.代码适用于人类,因此应该干净利落地阅读. (14认同)
  • 当我看到它时,这让我绝对疯了.对我而言,它使得类似但不同的线看起来完全相同.当事物欺骗性地相似但不完全相同时,我想要放大到最大的事实是它们确实是不同的,而不是一些视觉同质化使得更难以区分它们.IE:我经常看到你的最后一个例子,减去使用的"/ 2",这使得很难看出公式是对称的.当人们同样设法破坏倒数时,那就是当我蜷缩在桌子下面哭泣:)意见问题,没有冒犯意味着 (13认同)
  • 我完全同意应允许类似行中的运算符对齐 (4认同)

end*_*ith 20

PEP8

请注意,最重要的是,结束多行文档字符串的"""应该在一行上,并且最好以空行开头,例如:

"""Return a foobang

Optional plotz says to frobnicate the bizbaz first.

"""
Run Code Online (Sandbox Code Playgroud)

我觉得这很奇怪,因为它只是"无关的空白",并且没有明显的原因,对开场报价的处理与报价不同.

PEP 257给出了一个基本原理:

BDFL建议在多行文档字符串中的最后一个段落与其结束引号之间插入一个空行,将结束引号放在一行上.这样,可以在其上使用Emacs的fill-paragraph命令.

Emacs,真的吗?每个人都应该做一些奇怪的事情来迎合特定编辑工具中特定命令的特性?

我还认为将文档字符串的开头放在与引号相同的行(不是必需的,但建议的)上是很奇怪的,同时坚持将结束引用放在他们自己的行上.我认为这更符合逻辑,应该用于单行和多行文档字符串:

def foobang(bizbaz, plotz=None):
    """
    Return a foobang

    Optional plotz says to frobnicate the bizbaz first.
    """

    if plotz is not None:
        ...
Run Code Online (Sandbox Code Playgroud)

更新:粗体部分已被删除,现在它只是说"将结束引号单独放在一行",并且"汇总行可能与开头报价在同一行或在下一行".


Gle*_*ard 18

我不同意这点:

- Imports should usually be on separate lines, e.g.:

    Yes: import os
         import sys

    No:  import sys, os
Run Code Online (Sandbox Code Playgroud)

我总是一起写简单的进口.我认为将它们全部写在不同的行上并没有任何好处:它所做的只是在每个源文件的顶部添加膨胀,并将一些简洁的东西变成简单易用的东西,例如边界样板.一些非常冗长的东西,它开始很容易从其他文件中复制和粘贴.

这是立即可读和可理解的:

import sys, os, time, gc, inspect, math, doctest
Run Code Online (Sandbox Code Playgroud)

它简短,易于浏览,易于添加.import如果一行中有太多,当然或者我需要from导入,我会使用多个语句.

我也一般保持标准库进口的我自己的模块进口和其他库的独立,这与分组PEP8建议的概念一致.

  • 如果您更改任何导入,差异看起来不太好. (31认同)
  • @Tshepang:与在文件顶部有半页导入的混乱相比,它看起来很好. (7认同)
  • @flyingsheep为那些,你做`从foo import(\n bar,\nbaz,\n)` (3认同)

小智 17

标准至关重要,PEP 8是我坚持的非常好的风格指南.我不同意的唯一指导是数学运算符周围的间距.例如,PEP8坚持以下间距

Without PEP8                           With PEP8                
---------------------------------------------------------------- 
y = sqrt(x**2 + y**2)                  y = sqrt(x ** 2 + y ** 2) 
a*x**3 + b*x**2 + c*x + d              a * x ** 3 + b * x ** 2 + c * x + d 
10**(a*x + b)                          10 ** (a * x + b)  
F = V/(sqrt(g*h) + epsilon)            F = V / (sqrt(g * h) + epsilon) 
a*cos(nx/pi) + b*sin(nx/pi)            a * cos(nx / pi) + b * sin(nx / pi) 
Run Code Online (Sandbox Code Playgroud)

我想要顺从,但这是我正在努力的一个领域.还有其他人也觉得PEP8间距让数学难以阅读吗?

更新:

PEP8纠正建议的格式左侧,同时阻止右侧的格式:

是:

i = i + 1
submitted += 1
x = x*2 - 1
hypot2 = x*x + y*y
c = (a+b) * (a-b)
Run Code Online (Sandbox Code Playgroud)

没有:

i=i+1
submitted +=1
x = x * 2 - 1
hypot2 = x * x + y * y
c = (a + b) * (a - b)
Run Code Online (Sandbox Code Playgroud)

  • “如果使用具有不同优先级的运算符,请考虑在优先级最低的运算符周围添加空格。使用您自己的判断;但是,切勿使用多个空格,并且始终在运算符两侧添加相同数量的空格。二元运算符。” 所以我认为你的例子是无效的。根据 PEP8,这些是*好的*:`x = x*2 - 1`、`hypot2 = x*x + y*y`、`c = (a+b) * (ab)`,我认为它们'也很好。 (2认同)
  • 恕我直言,这些都不是可读的。:) (2认同)

dot*_*hen 6

我公司的风格指南专门要求标签,而不是空格.PEP 8暗示空间是可取的,但我们发现了相反的情况.我喜欢在VIM中看到代码缩进4个"空格",同事喜欢Emacs中的8个"空格".使用选项卡可以让我们设置编辑器以显示我们喜欢的代码.

请注意,在其他基于C语言中,缩进实际上只是格式化,但在Python 缩进中是语法,因此我们认为indentation level 2应该由2某些东西(即制表符)表示,4或者8某些东西(即空格).

缩进字符选择可能是最初的圣火焰战争(甚至在VIM/Emacs火焰战争之前),所以我确实希望被修改为遗忘以表达对该主题的意见!

  • 我认为,推荐空间的原因正是为了防止您和您的同事使用不同的标签间距量.你可以用4个空格缩进来设计看起来合理的东西,但是在8个空格缩进下它看起来不合理. (4认同)
  • @ScottRitchie“防止您和您的同事使用不同的制表符间距量”。这是真的吗?让我们把人体工程学抛到一边吧。你喜欢站着打字还是坐着打字?您喜欢一台 15 英寸笔记本电脑还是两台 24 英寸显示器?好吧,让我们来决定您使用哪一个。 (4认同)
  • 谢谢,斯科特.你指的是在连续的线上完成多个赋值时垂直对齐`=`符号的做法?如果是这样,无论使用哪些字符进行缩进,都可以使用空格. (3认同)
  • 很少有人在python中垂直对齐`=`.然而,通常将函数参数对齐`(`,你必须使用制表符和空格的组合,这只是为了容易搞乱.还有8个空格用于缩进?你的同事需要一些修复.接受4个空格标准,他只需要忍受它.如果你必须在其他机器上配对程序怎么办? (2认同)
  • @ScottRitchie 这可能是他们的意图,但仍然很愚蠢。如果你的缩进有太多层次以至于这开始成为一个问题,那么你已经在其他地方搞砸了。无论 PEP8 怎么说,缩进空格根本就是错误的。 (2认同)

小智 6

我的“承认违规”是关于“如果”

PEP8 在一行中没有说多个语句,所以如果我们必须这样做:

if cond:
    actions
    ...
Run Code Online (Sandbox Code Playgroud)

但是当只有一个动作时,我更喜欢一行,例如我更喜欢:

if a == 0: b = 0
Run Code Online (Sandbox Code Playgroud)

比:

if a == 0:
     b = 0
Run Code Online (Sandbox Code Playgroud)

  • 由于多种原因,我根本不使用“pep8”。现在这还只是一件事。 (4认同)

Jee*_*eet 5

多行条件等:PEP-8 明确表示二元运算符之后而不是之前中断。恐怕我看不出这有什么吸引力。对我来说,在条件之前中断更有意义,因此在换行/连续行中,每个子行都以条件开头:

if (condition1 \
        or condition2 \
        or condition3):
    do_something()
Run Code Online (Sandbox Code Playgroud)

可以看出,我还喜欢为子行添加额外的缩进,以便它们在视觉上与下面的块有偏移。PEP-8 没有明确说明这一点(是吗?),但示例中的子行与左括号对齐。

  • Python 中的连续反斜杠让我感觉自己正在阅读一个大的 C 预处理器宏。任何人都不应该有这样的感觉... (11认同)
  • 这里实际上不需要行尾反斜杠:一行不能在一组括号内结束,所以它们无论如何都会继续。顺便说一句,我同意你的观点,将条件放在一目了然的地方似乎更清楚。 (6认同)

vel*_*lis 5

PEP 8 的“问题”在于它涉及个人偏好的领域,而这些领域对大多数程序员来说都非常情绪化。

就我个人而言,驼峰式与下划线和列对齐指令是经常出现的问题。我也在这里看到了许多其他回复的观点,有时我故意破坏 PEP 8,因为在这种特殊情况下它只是“有意义”。

当我放弃并转向(使用)PEP 8 时,在我的 Python 编程生涯中有一点。对于大多数项目来说,这相对容易,所以现在我唯一的主要问题是列对齐。那个太乱了,不能服从(尽管我很讨厌这样做)。无论如何,由于我的“放弃”,我的代码现在对我的同事更具可读性 - 而且 - 令人惊讶的是:甚至对我来说也是如此(除了列对齐 :p )。

我还必须认识到 PEP 8 为 python 本身做了什么:在 2.x(不兼容)和 3.x(兼容)之间,我发现“始终知道”特定函数的名称要容易得多。Python 的“电池”现在分类更好了。


Tim*_*ara 3

当我编写小脚本时,我经常只使用两个空格。

我总是对文档字符串使用相同的模式:

def function():
    """
    Even if it's a single line.
    """
Run Code Online (Sandbox Code Playgroud)

  • Java 似乎喜欢 2 个空格,可能是因为在实际开始编写任何代码之前总是必须缩进两级。 (4认同)
  • 两空格缩进在任何语言中都很难阅读。我并不坚持使用四个空格缩进——我经常使用八个空格缩进,很大程度上是出于长期的习惯——但是阅读少于四个空格的缩进是非常不舒服的。 (3认同)
  • @Nick:出于所有我不喜欢 Java 的客观原因,我有一种感觉,如果它不是那样的话,我“主观上”会减少对它的讨厌。 (2认同)
  • 我发现这被否决了,这令人惊讶……问题不是寻求建议。它只是询问人们的行为方式。对此答案投反对票的唯一原因是您是否知道我在撒谎。 (2认同)