python 如何确定合适的元类?
How does the python determine the appropriate metaclass?
我可能在official doc中找到了答案,但我还是得不到。在第二种和第三种情况下,你能给我更详细或更直接的解释吗?如果你能给我一些例子,我将不胜感激!
The appropriate metaclass for a class definition is determined as follows:
- if no bases and no explicit metaclass are given, then
type()
is used;
- if an explicit metaclass is given and it is not an instance of type(), then it is used directly as the metaclass;
- if an instance of
type()
is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used.
假设您试图通过元类(在本例中为其中的两个)来实现单例模式。
class Singleton(type):
_inst = {}
def __call__(cls, *args, **kwargs):
return cls._inst.setdefault(cls, super().__call__(*args, **kwargs))
class Singleton2(Singleton):
def __call__(cls, *args, **kwargs):
return super().__call__(*args, **kwargs)
class SingletonClass1(metaclass=Singleton):
pass
class SingletonClass2(SingletonClass1, metaclass=Singleton2):
pass
class SingletonClass3():
pass
class SingletonClass4(SingletonClass2, metaclass=Singleton):
pass
type(class_obj)
函数 returns class_obj
的元类。
这是您的案例:
如果没有给出基类和显式元类,则使用 type();
type(SingletonClass3) --> <class 'type'>
2.如果给出了一个显式的元类,并且它不是type()的实例,那么直接作为元类使用;
`type(SingletonClass2) --> <class '__main__.Singleton2'>`
3. 如果 type() 的实例作为显式元类给出,或者定义了基类,则使用最派生的元类;
`type(SingletonClass4) --> <class '__main__.Singleton2'>`
如果你从SingletonClass1继承了SingletonClass2,却忘记从Singleton继承Singleton2,会导致TypeError。
The most derived metaclass is one which is a subtype of all of these
candidate metaclasses. If none of the candidate metaclasses meets that
criterion, then the class definition will fail with TypeError.
更新:
元类可以是函数,不是 type
的实例,因此第二种情况(如果给出了显式元类并且它不是类型 的实例)可以与这个。这是元类函数的 Singleton 实现。
def singleton_func(class_name, bases, attrs):
_inst = {}
def custom_new(cls):
return _inst.setdefault(cls, object.__new__(cls))
attrs['__new__'] = custom_new
return type(class_name, bases, attrs)
class SingletonClass5(metaclass=singleton_func):
pass
我可能在official doc中找到了答案,但我还是得不到。在第二种和第三种情况下,你能给我更详细或更直接的解释吗?如果你能给我一些例子,我将不胜感激!
The appropriate metaclass for a class definition is determined as follows:
- if no bases and no explicit metaclass are given, then
type()
is used;- if an explicit metaclass is given and it is not an instance of type(), then it is used directly as the metaclass;
- if an instance of
type()
is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used.
假设您试图通过元类(在本例中为其中的两个)来实现单例模式。
class Singleton(type):
_inst = {}
def __call__(cls, *args, **kwargs):
return cls._inst.setdefault(cls, super().__call__(*args, **kwargs))
class Singleton2(Singleton):
def __call__(cls, *args, **kwargs):
return super().__call__(*args, **kwargs)
class SingletonClass1(metaclass=Singleton):
pass
class SingletonClass2(SingletonClass1, metaclass=Singleton2):
pass
class SingletonClass3():
pass
class SingletonClass4(SingletonClass2, metaclass=Singleton):
pass
type(class_obj)
函数 returns class_obj
的元类。
这是您的案例:
如果没有给出基类和显式元类,则使用 type();
type(SingletonClass3) --> <class 'type'>
2.如果给出了一个显式的元类,并且它不是type()的实例,那么直接作为元类使用;
`type(SingletonClass2) --> <class '__main__.Singleton2'>`
3. 如果 type() 的实例作为显式元类给出,或者定义了基类,则使用最派生的元类;
`type(SingletonClass4) --> <class '__main__.Singleton2'>`
如果你从SingletonClass1继承了SingletonClass2,却忘记从Singleton继承Singleton2,会导致TypeError。
The most derived metaclass is one which is a subtype of all of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with TypeError.
更新:
元类可以是函数,不是 type
的实例,因此第二种情况(如果给出了显式元类并且它不是类型 的实例)可以与这个。这是元类函数的 Singleton 实现。
def singleton_func(class_name, bases, attrs):
_inst = {}
def custom_new(cls):
return _inst.setdefault(cls, object.__new__(cls))
attrs['__new__'] = custom_new
return type(class_name, bases, attrs)
class SingletonClass5(metaclass=singleton_func):
pass