嵌套 IF/ELSE 和 ELIF 之间的区别?
Difference between Nested IF/ELSE and ELIF?
这两种不同的代码组织之间是否存在语义或运行时差异?还是仅仅是简洁和空格的问题?
if something:
...
else:
if other:
...
else:
...
比
if something:
...
elif other:
...
else:
...
逻辑上没有区别。更喜欢第二种方式,使用elif
,可读性更好。
请注意,在抽象语法级别,它们完全等价:
>>> s1 = """\
... if something:
... ...
... else:
... if other:
... ...
... else:
... ..."""
...
>>> s2 = """\
... if something:
... ...
... elif other:
... ...
... else:
... ..."""
...
>>> ast.dump(ast.parse(s1)) == ast.dump(ast.parse(s2))
True
具体是elif
形式转化为嵌套if
形式的流控:
>>> ast.dump(ast.parse(s2))
"Module(body=[If(test=Name(id='something', ctx=Load()), body=[Expr(value=Ellipsis())], orelse=[If(test=Name(id='other', ctx=Load()), body=[Expr(value=Ellipsis())], orelse=[Expr(value=Ellipsis())])])])"
>>> # pip install astdump
>>> astdump.indented(s2)
Module
If
Name
Load
Expr
Ellipsis
If
Name
Load
Expr
Ellipsis
Expr
Ellipsis
两者都被编译为相同的字节码(至少在 CPython 中):
>>> def a():
... if something:
... return 1
... else:
... if other:
... return 2
... else:
... return 3
...
>>> def b():
... if something:
... return 1
... elif other:
... return 2
... else:
... return 3
...
>>> from dis import dis
>>> dis(a)
2 0 LOAD_GLOBAL 0 (something)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
5 >> 10 LOAD_GLOBAL 1 (other)
13 POP_JUMP_IF_FALSE 20
6 16 LOAD_CONST 2 (2)
19 RETURN_VALUE
8 >> 20 LOAD_CONST 3 (3)
23 RETURN_VALUE
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
>>> dis(b)
2 0 LOAD_GLOBAL 0 (something)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
4 >> 10 LOAD_GLOBAL 1 (other)
13 POP_JUMP_IF_FALSE 20
5 16 LOAD_CONST 2 (2)
19 RETURN_VALUE
7 >> 20 LOAD_CONST 3 (3)
23 RETURN_VALUE
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
所以唯一的区别是源代码的可读性。正如其他人所说,第二个变体更干净,应该是首选。
Python 是关于代码的可读性。您可以在更多 python 的情况下发现这一点。 Python遵循"Less is Better"的概念。
如果我们谈论你问的问题,除了redability之外,这两种格式没有任何区别。
这两种不同的代码组织之间是否存在语义或运行时差异?还是仅仅是简洁和空格的问题?
if something:
...
else:
if other:
...
else:
...
比
if something:
...
elif other:
...
else:
...
逻辑上没有区别。更喜欢第二种方式,使用elif
,可读性更好。
请注意,在抽象语法级别,它们完全等价:
>>> s1 = """\
... if something:
... ...
... else:
... if other:
... ...
... else:
... ..."""
...
>>> s2 = """\
... if something:
... ...
... elif other:
... ...
... else:
... ..."""
...
>>> ast.dump(ast.parse(s1)) == ast.dump(ast.parse(s2))
True
具体是elif
形式转化为嵌套if
形式的流控:
>>> ast.dump(ast.parse(s2))
"Module(body=[If(test=Name(id='something', ctx=Load()), body=[Expr(value=Ellipsis())], orelse=[If(test=Name(id='other', ctx=Load()), body=[Expr(value=Ellipsis())], orelse=[Expr(value=Ellipsis())])])])"
>>> # pip install astdump
>>> astdump.indented(s2)
Module
If
Name
Load
Expr
Ellipsis
If
Name
Load
Expr
Ellipsis
Expr
Ellipsis
两者都被编译为相同的字节码(至少在 CPython 中):
>>> def a():
... if something:
... return 1
... else:
... if other:
... return 2
... else:
... return 3
...
>>> def b():
... if something:
... return 1
... elif other:
... return 2
... else:
... return 3
...
>>> from dis import dis
>>> dis(a)
2 0 LOAD_GLOBAL 0 (something)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
5 >> 10 LOAD_GLOBAL 1 (other)
13 POP_JUMP_IF_FALSE 20
6 16 LOAD_CONST 2 (2)
19 RETURN_VALUE
8 >> 20 LOAD_CONST 3 (3)
23 RETURN_VALUE
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
>>> dis(b)
2 0 LOAD_GLOBAL 0 (something)
3 POP_JUMP_IF_FALSE 10
3 6 LOAD_CONST 1 (1)
9 RETURN_VALUE
4 >> 10 LOAD_GLOBAL 1 (other)
13 POP_JUMP_IF_FALSE 20
5 16 LOAD_CONST 2 (2)
19 RETURN_VALUE
7 >> 20 LOAD_CONST 3 (3)
23 RETURN_VALUE
24 LOAD_CONST 0 (None)
27 RETURN_VALUE
所以唯一的区别是源代码的可读性。正如其他人所说,第二个变体更干净,应该是首选。
Python 是关于代码的可读性。您可以在更多 python 的情况下发现这一点。 Python遵循"Less is Better"的概念。 如果我们谈论你问的问题,除了redability之外,这两种格式没有任何区别。