以下是不可取的,您会遇到很多问题和实现您的想法的极端情况,但是在 Python 3.1 及更高版本上,您可以通过覆盖内置挂钩来挂钩自定义类创建过程:__build_class__
import builtins
_orig_build_class = builtins.__build_class__
class SomeMockingMeta(type):
# whatever
def my_build_class(func, name, *bases, **kwargs):
if not any(isinstance(b, type) for b in bases):
# a 'regular' class, not a metaclass
if 'metaclass' in kwargs:
if not isinstance(kwargs['metaclass'], type):
# the metaclass is a callable, but not a class
orig_meta = kwargs.pop('metaclass')
class HookedMeta(SomeMockingMeta):
def __new__(meta, name, bases, attrs):
return orig_meta(name, bases, attrs)
kwargs['metaclass'] = HookedMeta
else:
# There already is a metaclass, insert ours and hope for the best
class SubclassedMeta(SomeMockingMeta, kwargs['metaclass']):
pass
kwargs['metaclass'] = SubclassedMeta
else:
kwargs['metaclass'] = SomeMockingMeta
return _orig_build_class(func, name, *bases, **kwargs)
builtins.__build_class__ = my_build_class
这仅限于自定义类,但确实为您提供了一个全能的钩子。
对于 3.1 之前的 Python 版本,您可以忘记挂钩类的创建。如果没有定义元类,Cbuild_class
函数直接使用 C 类型的值,它从不从模块中查找它,因此您不能覆盖它。type()
__builtin__