Python 在对象实例化时复制值或引用吗?

发布于 2024-09-04 02:13:06 字数 911 浏览 4 评论 0原文

也许是一个简单的问题,但我无法完全表达我的谷歌查询来在这里找到答案。我有在将对象传递给对象构造函数时复制对象的习惯,如下所示:

...
def __init__(self, name):
    self._name = name[:]
...

但是,当我运行以下测试代码时,Python 似乎没有必要对对象值进行深层复制对象实例化:

>>> class Candy(object):
...     def __init__(self, flavor):
...             self.flavor = flavor
...
>>> flav = "cherry"
>>> a = Candy(flav)
>>> a
<__main__.Candy object at 0x00CA4670>
>>> a.flavor
'cherry'
>>> flav += ' and grape'
>>> flav
'cherry and grape'
>>> a.flavor
'cherry'

那么,这里的真实情况是什么?谢谢!

编辑:

感谢@Olivier 的精彩回答。以下代码记录了 Python 通过引用复制的更好示例:

>>> flav = ['a','b']
>>> a = Candy(flav)
>>> a.flavor
['a', 'b']
>>> flav[1] = 'c'
>>> flav
['a', 'c']
>>> a.flavor
['a', 'c']

A simple question, perhaps, but I can't quite phrase my Google query to find the answer here. I've had the habit of making copies of objects when I pass them into object constructors, like so:

...
def __init__(self, name):
    self._name = name[:]
...

However, when I ran the following test code, it appears to not be necessary, that Python is making deep copies of the object values upon object instantiation:

>>> class Candy(object):
...     def __init__(self, flavor):
...             self.flavor = flavor
...
>>> flav = "cherry"
>>> a = Candy(flav)
>>> a
<__main__.Candy object at 0x00CA4670>
>>> a.flavor
'cherry'
>>> flav += ' and grape'
>>> flav
'cherry and grape'
>>> a.flavor
'cherry'

So, what's the real story here? Thanks!

EDIT:

Thanks to @Olivier for his great answer. The following code documents a better example that Python does copy by reference:

>>> flav = ['a','b']
>>> a = Candy(flav)
>>> a.flavor
['a', 'b']
>>> flav[1] = 'c'
>>> flav
['a', 'c']
>>> a.flavor
['a', 'c']

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半世蒼涼 2024-09-11 02:13:06

这是因为字符串是不可变的

运算符 += 相当令人困惑,如果对象是不可变的,实际上重新分配它所应用的变量:

s = 'a'
ids = id(s)
s += 'b'
ids == id(s) # False, because s was reassigned to a new object

因此,在您的情况下,一开始,两个 flava.flavor 指向同一个字符串对象:

flav --------\
               'cherry'
a.flavor ----/

但是当您编写 flav += 'andgrape' 时,变量 flav code> 被重新分配给一个新的字符串对象:

flav --------> 'cherry and grape'
a.flavor ----> 'cherry' # <-- that string object never changes

这很令人困惑,因为通常,当您对变量调用运算符时,它不会更改该变量。但仅在不可变对象的情况下,它才会重新分配变量。

因此,您问题的最终答案是,是的,在实例化时复制对象是有意义的,特别是如果您期望一个可变对象(通常是这种情况)。如果对象是不可变的,那么复制它也没什么坏处。

It is because strings are immutable.

The operator +=, rather confusingly, actually reassigns the variable it is applied to, if the object is immutable:

s = 'a'
ids = id(s)
s += 'b'
ids == id(s) # False, because s was reassigned to a new object

So, in your case, in the beginning, both flav and a.flavor point to the same string object:

flav --------\
               'cherry'
a.flavor ----/

But when you write flav += 'and grape' the variable flav gets reassigned to a new string object:

flav --------> 'cherry and grape'
a.flavor ----> 'cherry' # <-- that string object never changes

It is confusing, because usually, when you call an operator on a variable, it doesn't change the variable. But just in the case of an immutable object, it does reassign the variable.

So the final answer to your question is, yes, it makes sense to copy the objects upon instantiation, especially if you are expecting a mutable object (which is often the case). It the object was immutable, it will not harm to copy it anyway.

森末i 2024-09-11 02:13:06

看来没有必要

出现?你的问题完全是关于设计和意义的。这不是一个偏好或习惯问题。

类契约是否包含修改可变参数的能力?如果是这样,请勿复印。

类契约是否断言可变参数不会被修改?如果是这样,您必须复印一份。

类的契约定义完全回答了您的问题。

it appears to not be necessary

Appears? Your question is entirely about design and meaning. This is not a preference or habit question.

Does the class contract include the ability modify a mutable argument? If so, do NOT make a copy.

Does the class contract assert that a mutable argument will not be modified? If so, you MUST make a copy.

Your questions is answered entirely by the contract definition for the class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文