Python中的自分配安全吗?
这些天来,这个问题一直困扰着我:在Python中,当一个变量被分配给它自己时会发生什么?比如说,Python中的自分配安全吗?,python,python-3.x,grammar,Python,Python 3.x,Grammar,这些天来,这个问题一直困扰着我:在Python中,当一个变量被分配给它自己时会发生什么?比如说, a = a if (a>b) else b 我对引用计数机制知之甚少,对这个问题一无所知。如果你知道答案,请帮助我,谢谢 非常安全。Python将在=符号之后对所有内容进行排序,以便在分配变量之前计算表达式。我不认为有任何编程语言是不安全的(见下面@hadik的评论) 自赋值时,该变量的引用计数会发生什么变化 简言之,它会做正确的事情 在较长的回答中,要回答此问题,最好通过运行以下代码来查
a = a if (a>b) else b
我对引用计数机制知之甚少,对这个问题一无所知。如果你知道答案,请帮助我,谢谢 非常安全。Python将在
=
符号之后对所有内容进行排序,以便在分配变量之前计算表达式。我不认为有任何编程语言是不安全的(见下面@hadik的评论)
自赋值时,该变量的引用计数会发生什么变化 简言之,它会做正确的事情 在较长的回答中,要回答此问题,最好通过运行以下代码来查看反汇编:
import dis
def f(a, b):
a = a if (a>b) else b
dis.dis(f)
带注释的拆卸:
# the objects pointed by `a` and `b` starts with a positive refcount as they're part of the function argument
# increment refcount for the object pointed by `a` and `b`
0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
# COMPARE_OP (usually) returns boolean True/False
# increment the refcount of the boolean value
# and decrement the refcount of the object pointed by `a` and `b`
4 COMPARE_OP 4 (>)
# decrements the refcount of that boolean value
6 POP_JUMP_IF_FALSE 12
# increment refcount for the object pointed by `a`
8 LOAD_FAST 0 (a)
10 JUMP_FORWARD 2 (to 14)
# increment refcount for the object pointed by `b`
>> 12 LOAD_FAST 1 (b)
# decrement refcount for the object originally pointed by `a`
>> 14 STORE_FAST 0 (a)
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
一些背景信息:PythonVM是一个堆栈机器。LOAD_*操作将值推送到堆栈(并随着堆栈现在对对象的引用而增加其refcount),大多数其他操作将从堆栈中弹出值,并将计算结果推送到堆栈(减少消耗值的refcount,增加结果)。STORE_*操作将对象从堆栈顶部移动到变量(并减少该变量引用的原始对象的refcount;它不需要更改正在移动的对象的refcount,因为弹出堆栈并设置为变量实际上不会更改refcount)
简而言之,pythonrefcount总是做正确的事情,即使是多线程的(这要感谢GIL)。您真的不必担心refcount,如果对象可以从作用域访问,它就不会被垃圾收集。非常安全。Python将在
=
符号之后对所有内容进行排序,以便在分配变量之前计算表达式。我不认为有任何编程语言是不安全的(见下面@hadik的评论)
自赋值时,该变量的引用计数会发生什么变化 简言之,它会做正确的事情 在较长的回答中,要回答此问题,最好通过运行以下代码来查看反汇编:
import dis
def f(a, b):
a = a if (a>b) else b
dis.dis(f)
带注释的拆卸:
# the objects pointed by `a` and `b` starts with a positive refcount as they're part of the function argument
# increment refcount for the object pointed by `a` and `b`
0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
# COMPARE_OP (usually) returns boolean True/False
# increment the refcount of the boolean value
# and decrement the refcount of the object pointed by `a` and `b`
4 COMPARE_OP 4 (>)
# decrements the refcount of that boolean value
6 POP_JUMP_IF_FALSE 12
# increment refcount for the object pointed by `a`
8 LOAD_FAST 0 (a)
10 JUMP_FORWARD 2 (to 14)
# increment refcount for the object pointed by `b`
>> 12 LOAD_FAST 1 (b)
# decrement refcount for the object originally pointed by `a`
>> 14 STORE_FAST 0 (a)
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
一些背景信息:PythonVM是一个堆栈机器。LOAD_*操作将值推送到堆栈(并随着堆栈现在对对象的引用而增加其refcount),大多数其他操作将从堆栈中弹出值,并将计算结果推送到堆栈(减少消耗值的refcount,增加结果)。STORE_*操作将对象从堆栈顶部移动到变量(并减少该变量引用的原始对象的refcount;它不需要更改正在移动的对象的refcount,因为弹出堆栈并设置为变量实际上不会更改refcount)
简而言之,pythonrefcount总是做正确的事情,即使是多线程的(这要感谢GIL)。您真的不必担心refcount,如果对象可以从作用域访问,它将不会被垃圾收集。是的,它是安全的。把一个变量分配给它本身没有错。为什么你认为它不安全?旁注:你的代码也可以重写为
a=max(a,b)
ok,thx dudes。也许我只是想太多了,这是安全的。把一个变量分配给它本身没有错。为什么你认为它不安全?旁注:你的代码也可以重写为a=max(a,b)
ok,thx dudes。也许我只是觉得太多了,对象的自赋值可能会有问题。例如,对于c++
中的Eigen::Matrix
,如果执行a=a.transpose()
,则由于别名,它将无法工作。非常感谢你。你的回答对我很有用。我的另一个问题是:自我赋值时,该变量的引用计数会发生什么变化?我听说在Python中,赋值实际上复制了引用。计数是保持不变还是先是+1,然后是初始值的-1?@Goyo,Lie-Ryan写道:我认为没有任何编程语言不安全。
,因此这是对that@Bobholamovic:Python变量没有引用计数,只有对象有引用计数。我对你的另一个问题扩展了我的答案,因为在评论中解释有点复杂。@hadik:谢谢你提供的信息。注意C++非常有用。对象的自赋值可能存在问题。例如,对于c++
中的Eigen::Matrix
,如果执行a=a.transpose()
,则由于别名,它将无法工作。非常感谢你。你的回答对我很有用。我的另一个问题是:自我赋值时,该变量的引用计数会发生什么变化?我听说在Python中,赋值实际上复制了引用。计数是保持不变还是先是+1,然后是初始值的-1?@Goyo,Lie-Ryan写道:我认为没有任何编程语言不安全。
,因此这是对that@Bobholamovic:Python变量没有引用计数,只有对象有引用计数。我对你的另一个问题扩展了我的答案,因为在评论中解释有点复杂。@hadik:谢谢你提供的信息。注意C++非常有用。