Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将另一个变量赋给字符串是否会复制或增加引用计数_Python - Fatal编程技术网

Python 将另一个变量赋给字符串是否会复制或增加引用计数

Python 将另一个变量赋给字符串是否会复制或增加引用计数,python,Python,在David Beazley的“Python基本参考”第35页,他首先指出: 对于字符串等不可变数据,解释器 在程序的不同部分之间共享对象 然而,在同一页的后面,他说 对于数字和字符串等不可变对象,此赋值 有效地创建副本 但这不是矛盾吗?一方面,他说它们是共享的,但接着他说它们是复制的。它实际上创建了一个副本。它实际上并没有创建副本。拥有两个副本和拥有两个共享相同值的名称之间的主要区别在于,在后一种情况下,通过一个名称进行的修改会影响另一个名称的值。如果该值不能进行变异,那么这种差异就会消失,因

在David Beazley的“Python基本参考”第35页,他首先指出:

对于字符串等不可变数据,解释器 在程序的不同部分之间共享对象

然而,在同一页的后面,他说

对于数字和字符串等不可变对象,此赋值 有效地创建副本

但这不是矛盾吗?一方面,他说它们是共享的,但接着他说它们是复制的。

它实际上创建了一个副本。它实际上并没有创建副本。拥有两个副本和拥有两个共享相同值的名称之间的主要区别在于,在后一种情况下,通过一个名称进行的修改会影响另一个名称的值。如果该值不能进行变异,那么这种差异就会消失,因此对于不可变对象,是否复制该值几乎没有实际意义


在某些情况下,即使对于不可变类型,您也可以分辨副本和不同对象之间的差异(例如,通过使用
id
函数或
is
运算符),但这些对于Python内置的不可变类型(如字符串和数字)并不有用.

python中的赋值永远不会创建副本(仅当类成员的赋值通过使用
\uuuuuu setattr\uuuuuuu
属性或描述符重新定义时,技术上才可能)

那以后呢

a = foo()
b = a
foo
返回的任何内容都没有被复制,而是有两个变量
a
b
指向同一对象。不管对象是否是不可变的

但是,对于不可变对象,很难判断是否是这种情况(因为您无法使用一个变量对对象进行变异,并使用另一个变量检查更改是否可见),因此您可以自由地认为
a
b
确实不能相互影响

对于一些不可变的对象,Python也可以自由地重用旧对象,而不是创建新对象

a = x + y
b = x + y
如果
x
y
都是数字(因此总和是一个数字且不可变),则
a
b
可能都指向同一对象。请注意,没有这样的保证。。。也可能是它们将指向具有相同值的不同对象

需要记住的重要一点是,除非明确指示使用例如
copy
deepcopy
,否则Python永远不会制作副本。这对于可变对象非常重要,以避免意外

您可以看到一个常见的习语,例如:

class Polygon:
    def __init__(self, pts):
        self.pts = pts[:]
    ...

在这种情况下,
self.pts=pts[:]使用
代替self.pts=pts来复制整个点阵列,以确保在创建对象后,如果对传递给构造函数的列表应用更改,则点列表不会意外更改。

这会产生大量实际后果。考虑常用的<代码>如果变量不是“< /COD>”习惯用法(<代码> No.<代码>是一个不可更改的Python对象,如果对象<代码>不是< < /代码>,或者只是看起来像“代码>没有< /代码>,那就很重要了。原则上,你也可以用一个特殊的字符串来做同样的事情。如果x为None,那么使用
实际上没有什么实际效果,而如果x==None,那么使用
。它们只会在奇怪的角落情况下有所不同(例如,
x
是一个定义奇怪的
\uuuuu eq\uuu
测试的对象)。在字符串和数字上使用
is
的实际需要更少。不推荐使用<<代码> 用于特殊的“搁置”字符串/int,因为这种“搁置”是实现依赖的。请考虑使用“<代码> >如果X为“否”:)以检查您是否收到关键字参数的常见情况。如果要接受
None
作为值,该怎么办?你可以做
SENTINAL='';def foo(arg=SENTINAL);if(arg是SENTINAL):例如,arg=[]
。这不依赖于实现。是的。用
func(“”)
func(sentinel)
试试。哇,你说得对。非常有趣。我知道intepreter缓存了小整数,但我不知道它会重用这样的字符串。(其实我有点失望;^)。我仍然坚持认为
a is None
a==None
之间存在差异(因为你永远不知道人们在
\uuuuueq\uuuu
中会做什么,但对于非单例不可变类型,这种区别显然有点模糊。奇怪。谢谢你指出这一点。