Python中的缩进并不总是必要的吗?

时间:2014-11-07 00:49:52

标签: python if-statement

我遇到了一段代码(简化为问题),结构如下:

while True:
    if x == y: break

到目前为止,我对Python的理解是,解释器高度依赖于制表符/空格来理解循环和条件等内容,但上面的代码样式运行没有问题,这表明这不是真的。

有人可以解释细微差别吗?

4 个答案:

答案 0 :(得分:4)

有关详细信息,请参阅参考文档中的Compound Statements。但作为简要总结:

任何“复合语句”,例如if都可以 缩进套件语句,或内联简单语句列表 *

那么,这些之间的区别是什么?

if x == y:
    break

if x == y: break

真的,没什么,除了第一个通常被认为更具可读性和惯用性。 (PEP 8,官方风格指南,说第二种形式是“一般气馁”,但“有时可以将if / for / while与一个小身体放在同一条线上”。)**

它们具有完全相同的语义,性能等。它们甚至可以编译为完全相同的字节码。存在一个小的语法差异,但它只会影响您将这些错误消息嵌入各种非法构造中时会收到的错误消息。


那么,你能在那里放一些比break更复杂的东西吗?

是。请注意,这是一个简单的声明 list 。这意味着你可以有多个简单的语句,用分号分隔:

if x == y: print('Hey!'); x = -x; break

然而,这是非常糟糕的风格。除非你想要赢得代码 - 高尔夫比赛,否则不要这样做。

但也有限制。请注意,它是 简单 语句列表。这意味着没有复合语句。这是非法的:

if x == y: while True: print('loopy')

您可以看到简单陈述的完整列表here


*内联语句列表仍被视为官方语法中的套件。但是在松散的讨论中,套件通常意味着只是缩进的块替代,而不是内联替代。

**根据我的经验,经验丰富的开发人员在代码中看到这个的最常见的地方实际上是PEP 8所说的永远不会这样做的地方:一个有一堆空函数的类可能会让它们在一行,如def spam(self): pass。这可能会使他们难以粘贴到交互式解释器中,这可能就是PEP 8说永远不会这样做的原因。

答案 1 :(得分:2)

这里的缩进不是必需的,因为simple_stmtif suite中有simple statementsbreak

...
if_stmt      ::=  "if" expression ":" suite
                 ("elif" expression ":" suite)*
                 ["else" ":" suite]
...
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
...
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]
...

在这种情况下,不需要缩进。

您只能使用compound statements执行此操作,例如returnbreak,但您不能拥有{{3}},if之类{{1}没有缩进。

答案 2 :(得分:1)

在Python中,如果块只包含一个语句,则可以始终用一行替换目标块。

E.g。

def f(x): return x

def f(x):
    return x

是等价的。对于Python中的任何其他块期望语法也是如此:

  • if,else,elif,for,while,def,class,...

答案 3 :(得分:-1)

这是一个statemment和一个复合语句之间的区别。例如,在C中,您可能会执行类似

的操作
for(i=0; i<10; i++) printf("something");

for(i=0; i<10; i++) {printf("something");}

for循环只执行一个语句。但是,当您在花括号中包含多个语句时,例如

for(i=0; i<10; i++) {printf("something"); printf("something else");}

然后花括号内的整个东西被视为一个语句。

与Python相同......

if x == y: 
    print 'abcd'   # These two statements are treated as 1 block
    break          # of statements 

如果您只有一个语句,则不需要定义块。