(请注意,这适用于CPython,在其他实现中可能有所不同)
Python代码被解析并编译成字节码。您可以看到与^{}模块一起使用的说明。在>>> def f(x):
... x = [1, 2, 3, 4]
>>> dis.dis(f)
2 0 LOAD_CONST 1 (1)
2 LOAD_CONST 2 (2)
4 LOAD_CONST 3 (3)
6 LOAD_CONST 4 (4)
8 BUILD_LIST 4
10 STORE_FAST 0 (x)
12 LOAD_CONST 0 (None)
14 RETURN_VALUE
>>> print(dis.Bytecode(f).info())
Name: f
Filename:
Argument count: 1
Kw-only arguments: 0
Number of locals: 1
Stack size: 4
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: None
1: 1
2: 2
3: 3
4: 4
Variable names:
0: x
如您所见,整型字面值是常量,但每次都必须构建列表。在
这是一个相对快速的操作(可能比查找全局更快,但时间仍然可以忽略不计)
如果您有一个使用元组的函数g,它将作为常量加载:
^{pr2}$
但这似乎是一个过早乐观的例子。在
为函数存储的常量可以作为function.__code__.co_consts找到。在>>> g.__code__.co_consts
(None, 1, 2, 3, 4, (1, 2, 3, 4))
每次都要构建一个新列表的原因是,如果列表被更改,它不会影响每次加载的列表。在
如果不是常量列表,元组优化就消失了。在>>> def h(x):
... x = (1, 2, 3, x)
>>> dis.dis(h)
2 0 LOAD_CONST 1 (1)
2 LOAD_CONST 2 (2)
4 LOAD_CONST 3 (3)
6 LOAD_FAST 0 (x)
8 BUILD_TUPLE 4
10 STORE_FAST 0 (x)
12 LOAD_CONST 0 (None)
14 RETURN_VALUE
>>> print(dis.Bytecode(h).info())
Name: h
Filename:
Argument count: 1
Kw-only arguments: 0
Number of locals: 1
Stack size: 4
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
0: None
1: 1
2: 2
3: 3
Variable names:
0: x