如何解决+= 到 INPLACE_ADD 的 dis 代码 - 解释为什么它以这种方式工作
我有一个很简单的函数f,我用dis.dis反汇编了它:
def f():
a = "xxx"
print(id(a))
a = a + "A"
print(id(a))
a = a + "B"
print(id(a))
f()
from dis import dis
print(dis(f))
从https://pd.codechef.com/docs/py/2.7.9/library/dis.html我知道:
INPLACE_ADD():就地实现 TOS = TOS1 + TOS。
我的问题评论的输出是:
140387882962224
140387687265136
140387687265136
2 0 LOAD_CONST 1 ('xxx')
2 STORE_FAST 0 (a)
3 4 LOAD_GLOBAL 0 (print) # id(a)->140387882962224
6 LOAD_GLOBAL 1 (id)
8 LOAD_FAST 0 (a)
10 CALL_FUNCTION 1
12 CALL_FUNCTION 1
14 POP_TOP
4 16 LOAD_FAST 0 (a) # id(a) is 140387882962224,TOS = 'xxx'
18 LOAD_CONST 2 ('A') # TOS = 'A',TOS1 = 'xxx'
20 BINARY_ADD # TOS = TOS1+TOS = 'xxx'+'A' = 'xxxA'
22 STORE_FAST 0 (a) # id(a) is 140387882962224?
5 24 LOAD_GLOBAL 0 (print) id(a)->140387687265136
26 LOAD_GLOBAL 1 (id)
28 LOAD_FAST 0 (a)
30 CALL_FUNCTION 1
32 CALL_FUNCTION 1
34 POP_TOP
6 36 LOAD_FAST 0 (a)
38 LOAD_CONST 3 ('B')
40 BINARY_ADD
42 STORE_FAST 0 (a)
7 44 LOAD_GLOBAL 0 (print)
46 LOAD_GLOBAL 1 (id)
48 LOAD_FAST 0 (a)
50 CALL_FUNCTION 1
52 CALL_FUNCTION 1
54 POP_TOP
56 LOAD_CONST 0 (None)
58 RETURN_VALUE
在哪里可以看到字节码中 a 的 id 变化?
解决方法
BINARY_ADD
将一个新对象压入堆栈。那个新对象有一个新的 ID。任何现有对象都不会更改 ID。字符串和整数是不可变的;它们不会就地更改。
这实际上是理解 Python 的关键部分:名称和对象之间的分离。名称只是为了方便程序员——注意反汇编中根本没有名称。名称绑定到对象,所有对象都是匿名的,并存在于“对象云”中。 a
开始绑定到匿名字符串对象“xxx”。在您第一次更改后,a
现在绑定到一个带有“xxxA”的新字符串对象;字符串对象“xxx”不再需要,将被回收。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。