我正试图为我的班级创建一个元类。我试着用元类打印有关我们班的信息。
现在我已经创建了类的两个对象,但是第二个对象是在不引用我的元类的情况下创建的。
元类每个类只被调用一次吗??
如有任何帮助,将不胜感激。
谢谢
class Singleton(type):
def __new__(cls,name,bases,attr):
print (f"name {name}")
print (f"bases {bases}")
print (f"attr {attr}")
print ("Space Please")
return super(Singleton,cls).__new__(cls,name,bases,attr)
class Multiply(metaclass = Singleton):
pass
objA = Multiply()
objB = Multiply()
print (objA)
print (objB)发布于 2020-08-16 13:42:34
是的-只有在创建类时才调用元类的__new__和__init__方法。之后,在您的示例中,类将绑定到Multiply名称。在许多方面,它只是一个对象,就像Python中的任何其他对象一样。当您执行objA = Multiply()时,您不是在创建type(Multiply)的新实例,它是元类--您正在创建Multiply本身的一个新实例:调用Multiply.__new__和Multiply.__init__。
下面是这样的:在创建实例时调用__new__和__init__的Python机制是元类__call__方法中的代码。也就是说,就像使用__call__方法创建任何类并使用调用语法obj()的实例来调用type(obj).__call__(obj)一样,当您执行Multiply()时(在本例中)是Singleton.__call__(Multiply)。由于它没有实现,因此调用了辛格尔顿的超类,即type __call__方法--在那里调用了Multiply.__new__和__init__。
也就是说,上面的代码中没有任何东西可以使您的类表现为"singletons“。--更重要的是,--您不需要一个元类就可以在Python中拥有一个单独的实例。我不知道这东西是谁发明的,但它一直在四处流传。
First,如果您确实需要一个单例,只需编写一个普通的类,没有特殊的任何东西,创建您的单个实例,并记录应该使用的实例。就像人们使用None一样,没有人会一直获取对Nonetype的引用,并不断调用它以获得None引用:
class _Multiply:
...
# document that the code should use this instance:
Multiply = _Multiply()或者,如果您的代码需要实例化应该是单个实例的类,则可以使用类的方法本身来控制实例化,而不需要元类:
class Multiply:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super().__new__(cls)
# insert any code that would go in `__init__` here:
...
...
return cls._instance第三代仅为演示目的,请不要使用此方法,可以在__call__方法中构建元类机制来具有单元素:
class Singleton(type):
registry = {}
def __new__(mcls,name,bases,attr):
print(f"name {name}")
print(f"bases {bases}")
print(f"attr {attr}")
print("Class created")
print ("Space Please")
return super(Singleton,mcls).__new__(cls,name,bases,attr)
def __call__(cls, *args, **kw):
registry = type(cls).registry
if cls not in registry:
print(f"{cls.__name__} being instantiated for the first time")
registry[cls] = super().__call__(*args, **kw)
else:
print(f"Attempting to create a new instance of {cls.__name__}. Returning single instance instead")
return registry[cls]
class Multiply(metaclass = Singleton):
passhttps://stackoverflow.com/questions/63436512
复制相似问题