假设您需要将两个变量初始化为 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 语言发展的紧张原则。因此,当人们使用它来证明代码的合理性时,我总是很谨慎。与其试图从禅宗格言的集合中获得特定的方向,不如做语言中明确规定的语义正确的事情(例如,在这种情况下,链式赋值。)

10-06 15:32
查看更多