【问题标题】:When does Python Create a New ObjectPython什么时候创建一个新对象
【发布时间】:2017-01-31 22:44:34
【问题描述】:

Python 使用名称来引用对象。当我们说a = bab 现在指的是同一个对象,如果我们更改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 绑定到它。这是如何运作的?在这种情况下创建新对象的机制是什么?

这个问题不是 this one 的重复问题,因为我特别问的是在这种情况下对象创建是如何发生的,而另一个问题更普遍地是关于名称何时共享对象。

【问题讨论】:

  • 列表是可变的(使用copy 或使用[:] 切片来复制它们),整数是不可变的(它们每次都重新构建,就像字符串一样)
  • 从技术上讲,我不确定 a = a + 1 在这种特殊情况下 创建 一个新对象,因为 Python 缓存了 [-5, 256] 范围内的整数。相反,我认为这会将缓存中的预制整数对象分配给a。换句话说,a 现在将指向与b 不同的对象,但在该语句中没有创建对象。不过,如果我错了,请纠正我。
  • 类似,但问题不同。我的问题具体询问在给定操作中如何以及为什么创建新对象。旧的更一般地询问对象引用。
  • Tagc,我认为您对小整数的看法是正确的,因此请考虑大整数的相同问题。

标签: python


【解决方案1】:

我在 Luciano Ramalho 的Fluent 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 所示。

This question 也是相关的。

【讨论】:

  • 既然你是 OP,你可以决定它是对还是错,但我认为你并没有真正回答你自己的问题。为什么a = b 在某些情况下(例如大整数)可能会创建一个新对象,但在其他情况下(例如列表)却不会,仍有待解释。例如,是否可以调整 __new__ 或类的元类以重现自定义类的“类原始”行为?
  • 你是对的,这可能是部分答案。它确实帮助我理解了我在问题中提到的“对象创建机制”,然而,这是我最感兴趣的。
猜你喜欢
  • 2019-04-21
  • 2017-11-15
  • 2012-08-18
  • 1970-01-01
  • 2017-09-23
  • 2011-01-11
  • 2021-08-16
  • 2015-03-22
  • 1970-01-01
相关资源
最近更新 更多