class Meta(type) : def __init__(cls, name, bases, dct) : cls.attr = 'name' super().__init__(name, bases, dct) class A(metaclass = Meta) : attr = 'new_name' print(A.attr) # name How, then, to override the class attribute?
class Meta(type) : def __init__(cls, name, bases, dct) : cls.attr = 'name' super().__init__(name, bases, dct) class A(metaclass = Meta) : attr = 'new_name' print(A.attr) # name How, then, to override the class attribute?
This can be explained by adding a few extra print'ov:
class Meta(type): print("Meta body") def __init__(cls, name, bases, dct): print("Meta init for {name}".format(name=name)) cls.attr = 'name' super().__init__(name, bases, dct) def __new__(cls, name, bases, classdict): print("Meta new for {name}".format(name=name)) print(classdict) return type.__new__(cls, name, bases, classdict) class A(metaclass = Meta): print("A body") attr = 'new_name' def __init__(self): # Очевидно, не вызывается, потому что объект не создается print("A init") print(A.attr) # name Conclusion:
Meta body A body Meta new for A {'__qualname__': 'A', 'attr': 'new_name', '__module__': '__main__', '__init__': <function A.__init__ at 0x0000000004AB4D90>} Meta init for A name Apparently, the metaclass is not the parent of the class, but what this class creates. One of the goals of metaclasses is to change classes at the stage of their creation. What happened.
For more, perhaps, it is better to refer to the classic explanation: https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python
Source: https://ru.stackoverflow.com/questions/536139/
All Articles
Adefine theattrattribute ifAuses the meta metaclass that already sets theattrattribute on the class? That is, how to change the behavior provided by the metaclass in this case? Do you wantA.attr == 'new_name'orA().attr == 'new_name'or both both the class attribute and the object attribute? - jfs