python循环/关键字的黑暗角落.风格建议

1 python loops keyword

学习python,找到了这段代码.它从标准输入读取文本,并在完成时打印"完成".我从来没有见过任何其他语言elsewhile循环.我发现这个网站上的评论说这是一种类似于finally一段时间循环的pythonic方式.

import sys
while True:
    line = sys.stdin.readline()
    if not line:
        break
else:
    print("Done");
Run Code Online (Sandbox Code Playgroud)

问题是,这是pythonic吗?我工作的地方有一个非常严格的pep-8合规政策,所以我需要知道这是否合适.

aba*_*ert 6

使用while/ 的基本思想else当然是Pythonic-否则就不会出现这种语言.

但是,代码中有两个错误,每个错误都意味着您的else代码永远不会运行.包含从未执行过的代码可能不是Pythonic,只会误导读者.:)更重要的是,它可能不是你想要的.


首先,你无法退出循环(除了异常).readline在EOF返回一个空字符串,这可能是您要检查的内容:

while True:
    line = sys.stdin.readline()
    if line:
        print(line)
    else:
        break
else:
    print("Done")
Run Code Online (Sandbox Code Playgroud)

但接下来,我不确定while/ else做你认为它做了什么.我认为你期望它运行,else但是你退出循环.但正如文档解释的那样:

一个break在首套房执行的语句终止循环,不执行该else条款的套件.

换句话说,else只有当您正常退出时,该部件才会运行,条件变为false.显然while True永远不会变得虚假.

这就是重点:有时候你需要区分正常的循环和退出的循环if something: break; 这就是你使用的时候else:.如果你想以任何一种方式做同样的事情,那就去做吧:

while True:
    line = sys.stdin.readline()
    if line:
        print(line)
    else:
        break
print("Done")
Run Code Online (Sandbox Code Playgroud)

如果你想要一些"类似于finally"的东西,因为你可能有异常,答案很简单:使用finally:

try:
    while True:
        line = sys.stdin.readline()
        if line:
            print(line)
        else:
            break
finally:
    print("Done")
Run Code Online (Sandbox Code Playgroud)

作为旁注,readline用a 循环while并且break几乎不需要; 类似文件的对象就像sys.stdin是一个可迭代的行,readline返回相同的行,所以你可以这样做:

for line in sys.stdin:
    print(line)
print("Done")
Run Code Online (Sandbox Code Playgroud)

作为旁注,通常不会将Pythonic视为在代码中使用不必要的括号和分号 - 尤其是当它使您的代码看起来像C或Java之类的东西时会产生误导.虽然PEP 8仅作为Python stdlib的标准,但许多人将其用作自己的Python软件的指南,除非你有充分的理由不遵循它的推荐,否则最好遵循它的建议.您可以使用类似的工具pep8来检查您是否遵循指南.这只会抓住简单的东西,比如while(True):代替while Trueprint("Done");不是代替print("Done"),而是违反了这些简单的东西,分散了读者的注意力,让他们注意到你所询问的可能存在的更高级别的违规行为.