Python中的自分配安全吗?

Python中的自分配安全吗?,python,python-3.x,grammar,Python,Python 3.x,Grammar,这些天来,这个问题一直困扰着我:在Python中,当一个变量被分配给它自己时会发生什么?比如说, a = a if (a>b) else b 我对引用计数机制知之甚少,对这个问题一无所知。如果你知道答案,请帮助我,谢谢 非常安全。Python将在=符号之后对所有内容进行排序,以便在分配变量之前计算表达式。我不认为有任何编程语言是不安全的(见下面@hadik的评论) 自赋值时,该变量的引用计数会发生什么变化 简言之,它会做正确的事情 在较长的回答中,要回答此问题,最好通过运行以下代码来查

这些天来,这个问题一直困扰着我:在Python中,当一个变量被分配给它自己时会发生什么?比如说,

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++非常有用。