如果我使用包含现有实例的相同变量来定义类的第二个实例会发生什么?

dws*_*ein 4 python variables class instantiation

我不确定除了例子之外如何问这个问题.

让我们说我有一节课:

class Foo():
    pass
Run Code Online (Sandbox Code Playgroud)

我创建了一个它的实例:

foo = Foo()
    ...
Run Code Online (Sandbox Code Playgroud)

然后,作为我的程序的一部分,我重新创建具有相同名称的相同实例(重新启动游戏,但在另一个名为Bar的单独类中保持总分).

foo = Foo()
    ...
Run Code Online (Sandbox Code Playgroud)

(我不知道正确的术语)我没有编写任何代码来消除第一个实例.第一个实例是被删除还是被覆盖?它似乎适用于一个小程序.如果我多次这样做,我会遇到麻烦吗?

bra*_*zzi 13

让我试着以图形方式解释它.

当你这样做

foo = Foo()
Run Code Online (Sandbox Code Playgroud)

你是第一次在内存中创建一个类型的对象Foo(with Foo()),同时创建一个指向这个对象的变量:

在此输入图像描述

当你执行

foo = Foo()
Run Code Online (Sandbox Code Playgroud)

第二次,你正在创建另一个对象.同时,您正在使用相同的变量并将其指向新对象.当然,变量不再指向前一个对象:

在此输入图像描述

现在,第一个对象会发生什么?好吧,如果你的程序中没有其他变量指向它,它就没用了,因为你再也无法访问它了!在这种情况下,当解释器运行垃圾收集器时,对象将被从内存中销毁/释放.垃圾收集器是一种算法,它将查找每个无法访问的对象并将其删除.垃圾收集器不会每次都运行,因此可能需要一段时间来销毁对象.

所以,在你的场景中,会发生什么:

  • 将覆盖对第一个对象的引用,但该对象将存在.如果另一个变量指向它,它将不会被销毁.
  • 但是,如果没有其他变量指向它,则将来某个时候将删除该对象.


Tho*_*zco 5

基本(也可能是足够的)答案:

该变量foo被分配给一个新实例,该实例对前一个实例一无所知.它基本上与以下相同:

a = 1
a = 2
Run Code Online (Sandbox Code Playgroud)

在某些时候(可能比较晚),旧的实例foo将被垃圾收集(除非你仍然在其他地方引用它).

理解这一点的简单方法是foo名称只是指向实际对象的指针.如果您foo指向一个新对象,则foo指向一个新对象,句点.

相关细节:Singleton模式

有一些设计模式(singleton人们会想到),这可能会改变这种行为.

基本上, Foo.__new__类方法是决定你什么时候会得到的方法Foo().

可以构建此方法,以便它始终返回您创建的第一个实例,但这是非常偏离主题的.

这是一个示例实现:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
        return cls._instance
Run Code Online (Sandbox Code Playgroud)