Python正确的代码格式化(PEP8)



所以我刚刚学习了python中的"List Comprehensions"。其中一些对于单行(PEP8)来说太长了,我正试图找出最好的(最易读的)方法来把它们分开。

我想出了这个

questions = [
    (
        q,
        q.vote_set.filter(choice__exact='Y'),
        q.vote_set.filter(choice__exact='N'),
        request.session.get(str(q.id))
    )
    for q in questions
]

但是它仍然抱怨]之前的空白,具体的pep8错误是E202

我可能会这样做:

questions = [(q, 
              q.vote_set.filter(choice__exact='Y'), 
              q.vote_set.filter(choice__exact='N'), 
              request.session.get(str(q.id)))
                  for q in questions]

请记住,PEP8是为了与您的最佳判断一起使用;它们并不是要在所有情况下都绝对遵循。当多个规则冲突时,它们的结构也不是总是有意义的。

偶尔故意违反规则是可以的;像这样的检查器只是为了确保您不会意外地破坏。 编辑:把我的评论放到我的回答里。

你的代码看起来有点太像lisp式的括号语言或c式的花括号语言了,因为你把括号和圆括号放在了不同的行上。

在Python中,您只需使用缩进来显示在其他语言中通常在单独的行上使用大括号/圆括号/大括号显示的内容。如果你把你的代码做了修改,它和我的版本是一样的。

说真的,不要太担心PEP检查器。如果您确实喜欢将圆括号和方括号放在单独的行上所获得的额外空白,那么就这样做吧。它不会使它成为"坏代码",也不会降低可读性。

我想这取决于工具。哪个工具给你E202?我复制粘贴并尝试使用这个pep8工具,它没有给出任何错误。但是我特别在questions之后添加了一个空白,并得到了错误。

]上的E202表示它在此之前找到空白。确保代码中没有这个。试着在提问后尽快关闭]

考虑使用生成器表达式编写语句。

questions = ((q,
              q.vote_set.filter(choice__exact='Y'),
              q.vote_set.filter(choice__exact='N'),
              request.session.get(str(q.id)),) 
             for q in questions)

另外,并不是说它是"错误的",但总的来说,我不建议重新定义声明的变量,因为它可能会在代码中引起混乱。在本例中,将questions实例更改为另一种类型。

我也无法用您上面展示的代码重现您的PEP8警告。也许你可以把你的确切代码放在粘贴盒里?

PEP8的示例测试用例(如果使用——show-pep8选项)如下:

Avoid extraneous whitespace in the following situations:
- Immediately inside parentheses, brackets or braces.
- Immediately before a comma, semicolon, or colon.
Okay: spam(ham[1], {eggs: 2})
E201: spam( ham[1], {eggs: 2})
E201: spam(ham[ 1], {eggs: 2})
E201: spam(ham[1], { eggs: 2})
E202: spam(ham[1], {eggs: 2} )
E202: spam(ham[1 ], {eggs: 2})
E202: spam(ham[1], {eggs: 2 })
E203: if x == 4: print x, y; x, y = y , x
E203: if x == 4: print x, y ; x, y = y, x
E203: if x == 4 : print x, y; x, y = y, x

另外,我还没有实际使用Textmate,但是如果您正在进行类似于emacs的flymake模式的动态检查,那么也可能是pep8在旧版本的文件上被调用,并且当您保存文件时问题可能会消失。我们可能需要更多的信息来进一步调试。

至于列表理解本身的格式,您可能想看看另一个SO问题以及谷歌风格指南中的内容。我个人对你做这件事的方式没有意见。我想你也可以这样写

def _question_tuple(q):
    return (
        q,
        q.vote_set.filter(choice__exact='Y'),
        q.vote_set.filter(choice__exact='N'),
        request.session.get(str(q.id))
    )
question_tups = [_question_tuple(q) for q in questions]
但真正重要的是什么是最易读/可维护的,这取决于你自己的判断。