为啥使用 copy() 时字符串和数组的处理方式不同? [复制]

Posted

技术标签:

【中文标题】为啥使用 copy() 时字符串和数组的处理方式不同? [复制]【英文标题】:Why are strings and arrays treated differently when using copy()? [duplicate]为什么使用 copy() 时字符串和数组的处理方式不同? [复制] 【发布时间】:2019-11-04 23:47:55 【问题描述】:

我想知道为什么在下面的 sn-p 中,复制对象 b 中的属性表现不同。 b.lst 产生 a.lst 的更新值,但 b.str 保留分配给 a.str 的原始值。这是为什么呢?

>>> import copy
>>> class A(object):
...     pass
... 
>>> a = A()
>>> a.lst = [1, 2, 3]
>>> a.str = "Hola"
>>> b = copy.copy(a)
>>> a.lst.append(4)
>>> a.str = "Adios"
>>> print b.lst
[1, 2, 3, 4]
>>> print b.str
Hola

【问题讨论】:

请不要将列表称为数组。核心 Python 中有几种数组类型:元组、列表、字节数组和 array.array,非常流行的 Numpy 库也有数组。使用正确的术语可以减少歧义,并使人们在未来进行搜索时更容易。 这里的根本区别不是strlist 之间的区别,而是= 运算符(它重新绑定名称)和.append 方法(它只是改变对象)。如果您执行了a.lst = [1, 2, 3, 4],那么b.lst 将不受影响。 【参考方案1】:

根据[Python 3.Docs]: copy.copy(x)(强调是我的):

返回x浅拷贝

要真正复制列表(或任何可变对象),请改用copy.deepcopy

>>> import copy
>>>
>>> class A(object): pass  # In Python 3, object is extended by default
...
>>>
>>> a = A()
>>> a.lst = [1, 2, 3]
>>> a.str = "Hola"
>>>
>>> b = copy.copy(a)
>>>
>>> c = copy.deepcopy(a)
>>>
>>> a.lst.append(4)
>>> a.str = "Adios"
>>>
>>> print(b.str, b.lst)
Hola [1, 2, 3, 4]
>>>
>>> print(c.str, c.lst)
Hola [1, 2, 3]

【讨论】:

以上是关于为啥使用 copy() 时字符串和数组的处理方式不同? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥numpy数组的astype方法在转换类型时不修改输入?

为啥我的应用程序处理来自后端字符串的数组?

C语言,用指针方式定义的字符串为啥不能修改?

为啥使用字符串初始化没有 const 的数组时 gcc 不给出警告?

Golang string和[]byte的对比

为啥我不能用 `copy()` 复制切片?