就地修改和非就地修改之间的区别是一些实现细节还是Python程序员需要知道的东西?

就地修改和非就地修改之间的区别是一些实现细节还是Python程序员需要知道的东西?,python,Python,简而言之,在Python中 赋值语句可以是普通语句或扩充语句 变量的简单赋值 (例如,name=value)是创建新变量或将现有变量重新绑定到的方式 一个新的值。对对象属性(例如x.attr=value)的简单赋值是一个请求 到对象x以创建或重新绑定属性“attr”。对项目中的项目的普通赋值 容器(例如,x[k]=value)是对容器x创建或重新绑定项目的请求 使用索引或键k 扩充赋值(例如,name+=value)本身不能创建新的引用。 增广赋值可以重新绑定变量,要求对象重新绑定其中一个变量

简而言之,在Python中

赋值语句可以是普通语句或扩充语句

变量的简单赋值 (例如,name=value)是创建新变量或将现有变量重新绑定到的方式 一个新的值。对对象属性(例如x.attr=value)的简单赋值是一个请求 到对象x以创建或重新绑定属性“attr”。对项目中的项目的普通赋值 容器(例如,x[k]=value)是对容器x创建或重新绑定项目的请求 使用索引或键k

扩充赋值(例如,name+=value)本身不能创建新的引用。 增广赋值可以重新绑定变量,要求对象重新绑定其中一个变量 现有属性或项,或请求目标对象修改自身。当你 向一个对象发出请求,由该对象决定是否以及如何发出请求 尊重请求,以及是否提出异常

在增广赋值中,就像在普通赋值中一样,Python首先计算RHS 表示然后,当LHS引用一个对象时,该对象对 在适当的操作符就地版本中,Python使用RHS调用该方法 值作为其参数。由该方法适当修改LHS对象 并返回修改后的对象(第123页的“特殊方法”包括特殊方法) ods)。当LHS对象没有适当的就地特殊方法时,Python 将相应的二进制运算符应用于LHS和RHS对象,然后 将目标引用重新绑定到操作员的结果。例如,x+=y类似于
x=x.\uuuuidd\uuuuuuuy)
当x有用于就地添加的特殊方法时。 否则,x+=y类似于x=x+y

增广赋值从不创建其目标引用;目标必须已被删除 执行扩充赋值时绑定。增广分配可以重新绑定 目标引用到新对象,或修改目标所指向的同一对象 引用已绑定。相反,普通赋值可以创建或重新绑定 LHS目标引用,但它从不修改目标引用的对象(如果有) 埃伦斯以前是受约束的。对象和对对象的引用之间的区别 物体在这里至关重要。例如,x=x+y不会修改要修改的对象 名称x最初是绑定的。相反,它将名称x重新绑定以引用新对象。 相反,x+=y修改名称x绑定到的对象,如果 对象具有特殊方法
\uuuu iadd\uuuu
;否则,x+=y将名称x重新绑定到新的 对象,就像x=x+y一样

是一个赋值是否执行就地修改非就地赋值的区别(例如,用于增广赋值和普通赋值),Python的一些实现细节,Python程序员不必知道,还是属于程序员需要知道的语义?注:就地修改意味着更改内存区域中的值,而非就地分配则分配新的内存区域

如果答案是否定的,为什么Python程序员需要知道两者的区别?Python程序员是否需要意识到这种差异

我怀疑区别在于实现细节,Python程序员不需要知道区别,只需要知道赋值的语义

谢谢。

关于
\uuu i\uuu
特殊方法:

调用这些方法来实现增广算术赋值(
+=
-=
*=
=
/=
/=
%=
***=
&
)。这些方法应该尝试就地执行操作(修改self)并返回结果(可能是,但不一定是self)。如果未定义特定的方法,则扩充赋值将返回到正常方法。例如,如果
x
是具有
方法的类的实例,
x+=y
相当于
x=x.\uu iadd\uu(y)
。否则,将考虑
x.\uu添加\uuu(y)
y.\uu radd\uuuu(x)
,就像计算
x+y
一样。在某些情况下,扩充赋值可能会导致意外错误(请参阅),但这种行为实际上是数据模型的一部分

要回答您提出的问题,请执行以下操作:

就地修改和不修改(例如,用于增广赋值和普通赋值)之间的区别是Python的一些实现细节,Python程序员不必知道这些细节吗

是的,在为自定义对象实现数据模型时需要注意这一点

作为此类对象的用户,如果您理解这一点,您还可以更好地理解在使用增广赋值时您在做什么

为什么??如果未实现就地行为,则在执行扩充赋值时,会将名称或查找重新指派给作为操作标准实现结果的对象

作为实现者和用户,您需要了解这一点

提问者提出的后续问题: 我的问题是赋值是否执行就地修改而不是就地赋值,而不是调用哪个方法。就地修改意味着更改内存区域中的值,而非就地赋值创建新的内存区域。我想知道这种差异是程序员不需要知道的实现细节,还是属于progr所使用的语义
>>> def add_data(collection):
...     collection += ('tuple',)
... 
>>> l = []
>>> add_data(l)
>>> l
['tuple']
>>> t = tuple()
>>> add_data(t)
>>> t
()