如何手动/显式定义Python类?为何显式与隐式定义类不等价?
如何手动/显式定义与隐式定义等价的Python类?
首先,咱们先明确你给出的「隐式」类定义(也就是常规class语法):
class Super: pass class Klass1(Super): a = 1 i = 4 def get_i(self): return self.i
你尝试用type()手动构建等价类的思路是对的——毕竟Python里class语法本质就是调用type()的语法糖,但你的实现里有个关键问题:用lambda定义的get_i和用def定义的类方法不是完全等价的,这就是导致两个类不一致的核心原因。
为什么你的显式定义和隐式定义不等价?
用lambda创建的函数和类内def定义的函数有几个关键差异:
- 函数类型与标识:
lambda生成的是LambdaType实例,而def定义的是标准FunctionType实例(虽然LambdaType是FunctionType的子类,但很多工具比如inspect会做区分) - 名称属性:lambda的默认
__name__是'<lambda>',而类内def的方法__name__是'get_i' - 限定名称:类定义时,Python会自动给方法设置
__qualname__为'Klass1.get_i',而lambda的__qualname__默认还是'<lambda>' - 模块关联:类内方法的
__module__会自动关联到当前模块,lambda也需要手动设置才能匹配
这些差异会导致inspect或其他类型检查工具把两个类的get_i方法判定为不同的东西。
正确的手动/显式定义方法
要构建和Klass1完全等价的Klass2,你需要确保类字典里的方法和def定义的方法有一致的属性和类型。这里有两种靠谱的方式:
方式1:修正lambda的属性
如果你坚持用lambda,可以手动补全缺失的属性:
import types class Super: pass # 定义lambda后手动修正属性 get_i = lambda self: self.i get_i.__name__ = 'get_i' get_i.__qualname__ = 'Klass2.get_i' get_i.__module__ = __name__ # 匹配当前模块,可选但建议设置 # 构建类字典并创建类 dct = dict(a=1, i=4, get_i=get_i) Klass2 = type('Klass2', (Super,), dct)
方式2:用FunctionType构建标准函数
这种方式更接近Python内部处理def的逻辑,能完全复刻类内方法的特性:
import types class Super: pass # 编译函数代码,生成代码对象 get_i_code = compile("def get_i(self): return self.i", "<string>", "exec") # 从编译后的模块代码中提取函数的代码对象 get_i_code_obj = get_i_code.co_consts[0] # 创建标准FunctionType实例,关联当前模块的全局变量 get_i = types.FunctionType(get_i_code_obj, globals(), name='get_i') # 设置限定名称,和类名关联 get_i.__qualname__ = 'Klass2.get_i' # 构建类并创建 dct = dict(a=1, i=4, get_i=get_i) Klass2 = type('Klass2', (Super,), dct)
验证等价性
现在用你提到的检查工具验证:
import inspect LambdaType = type(lambda:0) print(inspect.isfunction(Klass1.get_i)) # True print(inspect.isfunction(Klass2.get_i)) # True print(isinstance(Klass1.get_i, LambdaType)) # False print(isinstance(Klass2.get_i, LambdaType)) # False print(Klass1.get_i.__name__ == Klass2.get_i.__name__) # True print(Klass1.get_i.__qualname__ == Klass2.get_i.__qualname__.replace('Klass2', 'Klass1')) # True
这样Klass1和Klass2就完全等价了。
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

