Python使用元类创建单例,super()的问题

    
    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

请问报错的原因是?应该怎样修改?

阅读 4.4k
1 个回答

我纯粹是对报错作修改,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__ 实现第一个实例吧?所以随便都可以。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题