委托类构造引发递归错误,如何在不修改create_instance的情况下解决?
解决元类实例化递归问题(不修改
create_instance) 问题原因
递归的本质是形成了无限循环调用链:
- 调用
Person()→ 触发元类PersonMetaclass的__call__方法 - 元类
__call__调用create_instance→create_instance里的cls(*args, **kwargs)再次触发元类__call__ - 上述步骤重复执行,最终触发递归深度超限错误
解决方案
要在不修改create_instance的前提下打破递归,核心是让create_instance中的cls(*args, **kwargs)调用绕过自定义元类的__call__方法。我们可以通过临时替换类的__call__方法为type的原生实现来实现这一点,调用完成后再恢复原方法。
修改后的完整代码如下:
def create_instance(cls, *args, **kwargs): print("CUSTOM LOGIC TO CREATE INSTANCE") return cls(*args, **kwargs) class PersonMetaclass(type): def __call__(cls, *args, **kwargs): # 保存原__call__方法,避免永久修改类行为 original_call = cls.__call__ try: # 临时替换为type的原生__call__,绕过自定义元类逻辑 cls.__call__ = type.__call__ # 此时调用create_instance中的cls()不会触发递归 return create_instance(cls, *args, **kwargs) finally: # 恢复原__call__方法,保证后续实例化正常执行 cls.__call__ = original_call class Person(metaclass=PersonMetaclass): def __init__(self, *args, **kwargs): print("Person instance created") person = Person()
运行结果
执行代码后会输出:
CUSTOM LOGIC TO CREATE INSTANCE Person instance created
简化终端用户操作
如果要让用户更简便地使用,你可以封装一个基类,用户只需继承该基类即可,无需手动指定元类:
# 框架侧封装 class FrameworkBase(metaclass=PersonMetaclass): pass # 用户侧使用 class Person(FrameworkBase): def __init__(self, *args, **kwargs): print("Person instance created")
用户只需要继承FrameworkBase,就能自动获得实例构造的自定义逻辑支持,无需关心元类细节。
内容的提问来源于stack exchange,提问作者Pithikos
相关产品推荐
相关产品推荐

