除了举例之外,我不知道如何问这个问题。
假设我有一堂课:
class Foo():
pass
我创建了一个实例:
foo = Foo()
...
然后,作为我的程序的一部分,我重新创建具有相同名称的相同实例(重新开始游戏,但在另一个名为 Bar 的单独类中保留总分)。
foo = Foo()
...
(我不知道正确的术语)我还没有编写任何代码来消除第一个实例。第一个实例是消除还是覆盖?它似乎适用于一个小程序。如果我多次这样做,我会遇到麻烦吗?
除了举例之外,我不知道如何问这个问题。
假设我有一堂课:
class Foo():
pass
我创建了一个实例:
foo = Foo()
...
然后,作为我的程序的一部分,我重新创建具有相同名称的相同实例(重新开始游戏,但在另一个名为 Bar 的单独类中保留总分)。
foo = Foo()
...
(我不知道正确的术语)我还没有编写任何代码来消除第一个实例。第一个实例是消除还是覆盖?它似乎适用于一个小程序。如果我多次这样做,我会遇到麻烦吗?
让我试着用图形来解释它。
当你这样做
foo = Foo()
第一次,您在内存中创建一个类型的对象(使用),同时创建一个指向该对象的变量:FooFoo()

当你执行
foo = Foo()
第二次,您正在创建另一个对象。同时,您使用相同的变量并将其指向新对象。当然,变量将不再指向前一个对象:

现在,第一个对象会发生什么?好吧,如果您的程序中没有其他变量指向它,那它是没有用的,因为您不能再访问它了!在这种情况下,当解释器运行垃圾收集器时,对象将被销毁/从内存中释放。垃圾收集器是一种算法,它将查找每个不可访问的对象并将其删除。垃圾收集器并非每次都运行,因此对象被销毁可能需要一段时间。
所以,在你的场景中,会发生什么:
该变量foo被分配给一个新实例,该实例对前一个实例一无所知。它基本上与以下内容相同:
a = 1
a = 2
在某个时候(可能迟早),旧实例foo将被垃圾收集(除非您在其他地方仍然有对它的引用)。
理解这一点的简单方法是,foo名称只是指向实际对象的指针。如果您foo指向一个新对象,则foo指向一个新对象,句号。
有一些设计模式(singleton想到的那个)可能会改变这种行为。
基本上, Foo.__new__classmethod 决定了当你做的时候你会得到什么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
第一个foo = Foo():
它创建一个新的实例对象并将其分配给foo,seefoo只是对返回的对象的引用Foo()
第二foo = Foo()
它创建一个新的实例对象并将其分配给foo,并且先前的实例对象Foo()被垃圾收集,因为没有指向它的变量。
例子:
>>> class Foo:
... pass
...
>>>
>>> foo=Foo()
>>> id(foo) #foo points to an object with id 3077166220L
3077166220L
>>> foo=Foo() #now foo points to some other object and the object with id 3077166220L is garbage collected
>>> id(foo)
3077166252L
>>>
>>>
>>> temp=foo #now both foo and temp point to same object i.e 3077166252L
>>> foo=Foo() #assign foo to a new object
>>> id(temp) #temp still points 3077166252L ,so it's not garbage collected
3077166252L
>>> id(foo) #it points to a new object
3077166092L
有几点需要注意。
foo = Foo()变量分配foo类型对象的实例时Foo。通过调用不带任何参数Foo()的类的构造函数来创建此实例。FooFoo()都会创建一个新实例。因此,foo = Foo()在您的代码中重复将创建Foo该类的多个实例,并将它们分配给变量foo。变量指向的早期实例foo将不再具有引用并且可以被垃圾收集(假设您同时没有为这些实例分配任何其他引用)。因此,您用来描述问题的词语
创建与现有实例同名的类的第二个实例
其实是不对的。因为您没有创建另一个“同名”实例。您正在创建另一个实例,并将其分配给“相同的变量”。
Foo()会创建一个新实例(按顺序调用类方法__new__和实例方法)__init____del__在该实例上调用实例方法)你最终绑定了一个新的 Foo 对象foo,你的旧Foo对象将失去一个引用。如果一个对象没有任何引用,那么它将在下一次垃圾回收中被回收。
第二个将覆盖第一个。(它取代了模块全局字典中的名称,所有全局变量、函数和类都存储在其中)。
但是,您创建的 foo = Foo() 将继续使用创建时的原始实现,直到您创建新的 foo = Foo()。