假设您需要将两个变量初始化为 None。
在 Zen of Python 之后应该使用哪种方式(以及为什么)?
(假设以下方法是您的选择)
解包赋值
a, b = None, None # Explicit
或者
链式赋值
a = b = None # faster. Still readable (perhaps less explicit than unpack?)
“显式更好”的概念似乎适用于任何一种情况。
最佳答案
解包赋值与链式赋值
以上是明确的。它明确且不必要地创建了一个额外的数据结构:
a, b = None, None
#makes (None, None) before unpacking and giving to a and b
相反,执行链式分配。这也明确地做你想要的,而不做任何不必要的事情。我认为它是该语言的优雅应用:
a = b = None
如果您觉得以上内容在其独特的上下文中过于密集而无法阅读,您也可以毫无羞耻地这样做:
a = None
b = None
反汇编,Python 2 和 3:
import dis
def tupleunpack():
a, b = None, None
def chainedassignment():
a = b = None
def multiline():
a = None
b = None
>>> dis.dis(tupleunpack)
2 0 LOAD_CONST 1 ((None, None))
3 UNPACK_SEQUENCE 2
6 STORE_FAST 0 (a)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
>>> dis.dis(chainedassignment)
2 0 LOAD_CONST 0 (None)
3 DUP_TOP
4 STORE_FAST 0 (a)
7 STORE_FAST 1 (b)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
>>> dis.dis(multiline)
2 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (a)
3 6 LOAD_CONST 0 (None)
9 STORE_FAST 1 (b)
12 LOAD_CONST 0 (None)
15 RETURN_VALUE
反汇编表明元组解包会创建一个不必要的数据结构。
多行不必要地加载 None 两次。就消除不必要的过程而言,链式分配更可取。
性能,Python 3:
元组解包似乎也需要更多的时间:
>>> import timeit
>>> timeit.repeat(tupleunpack)
[0.09981771527421301, 0.10060130717376126, 0.10003051661827556]
>>> timeit.repeat(chainedassignment)
[0.09882977371520241, 0.0981032306866183, 0.0982816216005773]
>>> timeit.repeat(multiline)
[0.09878721344639274, 0.09834682031024045, 0.09854603858978805]
Zen 来证明代码?
此外,Python 之禅描述了 Python 语言发展的紧张原则。因此,当人们使用它来证明代码的合理性时,我总是很谨慎。与其试图从禅宗格言的集合中获得特定的方向,不如做语言中明确规定的语义正确的事情(例如,在这种情况下,链式赋值。)