class MusicPlayer(object):
instance = None # 必须先定义类属性,不能像 实例.属性 这样创建类属性
def __new__(cls, *args, **kwargs):
print("创建实例,分配内存空间")
if cls.instance:
return cls.instance
else:
cls.instance = super().__new__(cls)
return cls.instance
def __init__(self):
print("播放器初始化")
player1 = MusicPlayer()
print(player1)
player2 = MusicPlayer()
print(player2) # 会输出相同的内存地址,无论创建多少次,都只有一个实例
下面是尝试用元类来实现以上功能
------------------------------------------------------------------------
class OneObject(type):
def one(cls):
print("创建实例,分配内存空间")
if cls.instance:
return cls.instance
else:
cls.instance = super().__new__(cls)
return cls.instance
def __new__(cls, class_name, class_parents, class_attr):
class_attr["instance"] = None
class_attr["__new__"] = OneObject.one
return type(class_name, class_parents, class_attr)
class MusicPlayer(object, metaclass=OneObject):
def __init__(self):
print("初始化播放器")
player1 = MusicPlayer()
我的逻辑是使用元类给MusicPlayer添加一个类属性 instance = None ,然后把one函数传给MusicPlayer类的__new__方法来创建单例。
程序会在输出“创建实例,分配内存空间”后报错:
super(type, obj): obj must be an instance or subtype of type
请问报错的原因是?应该怎样修改?
我纯粹是对报错作修改,super(type, obj): obj must be an instance or subtype of type
因为object是type的实例,所以照搬试一试:
cls.instance = super(type, object).__new__(cls)
测试后成功实现。
#object是type的实例,但是type又是object的子类。
后来发现super(type,str或者cls)都可以。
或者super(MusicPlayer, MusicPlayer)或super(cls,cls)也行。
或许super(type, object).__new__(cls)
因为super() 实在MusicPlayer这个类调用的,MusicPlayer类是type的实例,所以super()第一个参数就是type, 所以cls也是type,而第二个参数只要是type的实例就可以了,
这里只是要以“原始”的__new__ 实现第一个实例吧?所以随便都可以。