Aus*_*art 2 python if-statement structure
这两个不同的代码组织之间是否存在语义或运行时差异?或者仅仅是简洁和空白的问题?
if something:
...
else:
if other:
...
else:
...
Run Code Online (Sandbox Code Playgroud)
比.
if something:
...
elif other:
...
else:
...
Run Code Online (Sandbox Code Playgroud)
没有逻辑差异.首选第二种方法,它更具可读性.
请注意,在抽象语法级别,它们完全等效:
>>> s1 = '''if something:
... ...
... else:
... if other:
... ...
... else:
... ...'''
...
>>> s2 = '''if something:
... ...
... elif other:
... ...
... else:
... ...'''
...
>>> ast.dump(ast.parse(s1)) == ast.dump(ast.parse(s2))
True
Run Code Online (Sandbox Code Playgroud)
具体来说,第二种形式转换为第一种形式:
>>> 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
Run Code Online (Sandbox Code Playgroud)
两者都编译为相同的字节码(至少在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
Run Code Online (Sandbox Code Playgroud)
所以唯一的区别是源的可读性.正如其他人所说,第二种变体更清洁,应该是首选.