Python 何时创建新对象?

4

Python使用名称来引用对象。当我们说a = b时,ab现在引用同一对象,如果我们改变了a,那么在b中也会看到相同的变化。例如:

a = [1, 2, 3]
b = a

a.append(4)

print(b)

将打印[1, 2, 3, 4]

然而,有些操作确实会创建新的对象。例如:

a = 1
b = a

a = a + 1

print(b)

将打印1。显然,行a = a + 1以某种方式创建了一个值为a + 1的新对象,并将名称a绑定到它上面。这是如何工作的?在这种情况下创建新对象的机制是什么?

这个问题不是这个问题的重复,因为我特别询问对象在这种情况下如何创建,而另一个问题更普遍地涉及名称共享对象的情况。


2
列表是可变的(使用copy或切片[:]来复制它们),整数是不可变的(它们每次都被重新创建,就像字符串一样)。 - Chris_Rands
4
可能是如何理解Python中的赋值的重复问题。 - Josh Lee
从技术上讲,我不确定在这种情况下 a = a + 1 是否会 创建 一个新对象,因为 Python 缓存范围在 [-5,256] 的整数。相反,我认为将分配来自缓存的预先制作的整数对象给 a。换句话说,a 现在将指向与 b 不同的对象,但在该语句中并未创建任何对象。如果我有错,请纠正我。 - Tagc
它们很相似,但问题不同。我的问题具体询问在给定操作中如何以及为什么创建新的对象。旧问题更一般地询问对象引用。 - PProteus
Tagc,我认为你对于小整数是正确的,那么考虑一下大整数的同样问题。 - PProteus
1个回答

2
我在Luciano Ramalho的书《流畅的Python》中找到了有关对象创建机制的信息。
Ramalho解释说,虽然通常认为__init__是“构造函数”,但实际上,对象是通过调用__new__方法创建的。这是一个类方法,它返回一个类的实例,该实例作为第一个参数(通常是“self”)传递给__init__。因此,__init__是初始化器,而不是构造函数。
以下示例说明了这一点:
class C(object):
    def __new__(cls):
        new_inst = object.__new__(cls)
        print new_inst.__dict__
        new_inst.var_1 = 1
        return new_inst

    def __init__(self):
        print self.__dict__
        self.var_2 = 2

a = C()             # Prints:
                        # {}
                        # {'var_1': 1}
print a.__dict__    # returns {'var_2': 2, 'var_1': 1}

b = C.__new__(C)    # Prints:
                        # {}
print b.__dict__    # returns {'var_1': 1}

b.__init__()        # Prints:
                        # {'var_2': 2, 'var_1': 1}
print b.__dict__    # returns {'var_2': 2, 'var_1': 1}

这行代码 a = C() 调用了 __new____init__,根据 __dict__ 的输出可见。我们可以把它分解成单独的调用,就像对象 b 一样。

这个问题也相关。


1
既然你是 OP,那么决定对错就由你来决定,但我认为你并没有真正回答自己的问题。仍需解释为什么 a = b 在某些情况下(如大整数)可能会创建一个新对象,而在其他情况下(如列表)则不会。例如,是否可以调整类的 __new__ 或元类以为自定义类复制“原始类型”行为? - jdehesa
你说得对,这可能只是一个部分回答。它确实帮助我理解了我在问题中提到的“对象创建机制”,这也是我最感兴趣的。 - PProteus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接