Python适当的代码格式化(PEP8)

4
所以我刚学会了Python中的"列表推导式"。其中一些太长了,不适合单行(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
这是在一个缩进块中。

你用什么工具来“检查”你的代码?是Pylint吗? - monkut
1
如果你在意PEP8,choice__exact 应该改为 choice_exact。顺便说一句,我不太关心多行列表推导式的缩进,只要可读性好就可以了。 - JBernardo
2
@JBernardo 我猜测 choice__exact 这个名称来自 Django API。 - brandizzi
1
PEP对行首和行尾的下划线赋予特殊含义,但对于内部的双下划线并无意见。 - agf
@Daniel,我很想听听你会怎么做,我正在学习Django... - jondavidjohn
显示剩余2条评论
4个回答

1

我可能会这样做:

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检查器。如果您真的喜欢从将括号和括号放在单独的行上获得的额外空格,请这样做。这不会使它成为“糟糕的代码”,也不会降低可读性。

对于 Python 我还是新手,所以我不知道是否有更好的方法来分解它们并且想要从一开始就编写高质量的代码。 - jondavidjohn
对我来说,为了这个目的而分开行似乎不是一个好主意。这个感觉是正确的。 - gorlum0

0

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

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实例更改为另一种类型。

只有在您仅需要对新的“questions”对象进行一次迭代时才使用生成器表达式。我认为这根本不是生成器表达式的好用法。 - agf
是的,上下文很重要。在正确的情况下,生成器更好,因为您可以推迟很多方法调用,直到结果更有意义。 - cmcginty

0

我试图使用你上面展示的代码复现PEP8警告,但是未能成功。或许你可以将你的完整代码放在pastebin里?

如果你使用--show-pep8选项,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问题以及Google样式指南的建议。我个人对你的做法没有任何问题。我想你也可以做一些像这样的事情

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]

但这实际上取决于哪种写法最易读懂/易于维护,这需要根据个人判断。


他在闭合的 )] 前明显有空格或换行符,这违反了他工具中的规则。 - agf

0

这取决于工具,我猜。哪个工具给你 E202?我复制粘贴并尝试了这个 pep8 工具,它没有给出任何错误。但是我特意在 questions 后面加了一个空格,然后就出现了错误。

] 上的 E202 表示在那之前找到了一个空格。确保代码中没有这个。尝试在 questions 之后立即关闭 ]


好的,它前面有空格是因为它在代码块内部。 - jondavidjohn
他的意思是该行有缩进。实际上,这并不重要,因为换行符本身就是空格。 - agf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接