如何将Python子类向上转换为父类?临时属性处理咨询
解决方案
1. 用私有属性隐藏临时值
给子类的临时属性加双下划线前缀,Python会自动对这个属性做名称修饰,外部代码无法直接访问。如果担心父类的to_json会把修饰后的属性包含进去,用完临时属性后手动删除即可。
class Parent: def __init__(self, arg1, arg_needs_to_be_set, arg3): self.arg1 = arg1 self.arg_needs_to_be_set = arg_needs_to_be_set self.arg3 = arg3 def set_attribute1(self): self.arg_needs_to_be_set = "set_by_method" def to_json(self): # 遍历实例属性生成JSON,过滤下划线开头的内部属性 return {k: v for k, v in self.__dict__.items() if not k.startswith('_')} class Child(Parent): def __init__(self, custom_arg, arg1, arg3): super().__init__(arg1, arg_needs_to_be_set=None, arg3=arg3) self.__custom_arg = custom_arg # 双下划线触发名称修饰 # 使用流程 child = Child("temp_value", "arg1_val", "arg3_val") # 用临时属性完成赋值逻辑 child.arg_needs_to_be_set = child.__custom_arg child.set_attribute1() # 删除修饰后的临时属性,确保to_json干净 del child._Child__custom_arg print(child.to_json()) # 输出里没有临时属性
2. 用弱引用字典存临时属性
完全不用修改类,用WeakKeyDictionary关联Parent实例和临时值。这个字典不会把属性绑在实例上,外部完全看不到,也不会影响to_json输出;而且实例被回收时,字典里的对应条目会自动消失,不会造成内存泄漏。
import weakref # 定义弱引用字典存储临时属性 temp_attrs = weakref.WeakKeyDictionary() class Parent: def __init__(self, arg1, arg_needs_to_be_set, arg3): self.arg1 = arg1 self.arg_needs_to_be_set = arg_needs_to_be_set self.arg3 = arg3 def set_attribute1(self): self.arg_needs_to_be_set = "set_by_method" def to_json(self): return {k: v for k, v in self.__dict__.items()} # 使用流程 parent = Parent("arg1_val", None, "arg3_val") # 把临时值和实例关联存入字典 temp_attrs[parent] = "custom_temp_value" # 用临时值完成逻辑 parent.arg_needs_to_be_set = temp_attrs[parent] parent.set_attribute1() # 用完删除临时值(可选,弱引用会自动清理) del temp_attrs[parent] print(parent.to_json()) # 完全看不到临时属性的痕迹
3. 临时给Parent实例加属性,用完就删
最简单的方式:直接给Parent实例加个临时属性,用单下划线开头标识内部使用,完成逻辑后立刻删除,这样to_json输出时就不会包含它。
class Parent: def __init__(self, arg1, arg_needs_to_be_set, arg3): self.arg1 = arg1 self.arg_needs_to_be_set = arg_needs_to_be_set self.arg3 = arg3 def set_attribute1(self): self.arg_needs_to_be_set = "set_by_method" def to_json(self): return {k: v for k, v in self.__dict__.items()} # 使用流程 parent = Parent("arg1_val", None, "arg3_val") # 临时添加内部属性 parent._custom_arg = "temp_value" # 用临时属性完成赋值 parent.arg_needs_to_be_set = parent._custom_arg parent.set_attribute1() # 立刻删除临时属性 del parent._custom_arg print(parent.to_json()) # 输出干净,无临时属性
4. 子类转纯净Parent实例
如果一定要用子类,最后可以创建新的Parent实例,把子类中属于Parent的属性复制过去,得到完全纯净的Parent对象。这种方式适合属性不多的场景。
class Parent: def __init__(self, arg1, arg_needs_to_be_set, arg3): self.arg1 = arg1 self.arg_needs_to_be_set = arg_needs_to_be_set self.arg3 = arg3 def set_attribute1(self): self.arg_needs_to_be_set = "set_by_method" def to_json(self): return {k: v for k, v in self.__dict__.items()} class Child(Parent): def __init__(self, custom_arg, arg1, arg3): super().__init__(arg1, arg_needs_to_be_set=None, arg3=arg3) self.custom_arg = custom_arg # 使用流程 child = Child("temp_val", "arg1_val", "arg3_val") child.arg_needs_to_be_set = child.custom_arg child.set_attribute1() # 复制属性生成纯净Parent实例 pure_parent = Parent( arg1=child.arg1, arg_needs_to_be_set=child.arg_needs_to_be_set, arg3=child.arg3 ) print(pure_parent.to_json()) # 不含custom_arg print(type(pure_parent)) # 类型为Parent,而非Child
内容的提问来源于stack exchange,提问作者Conor
相关产品推荐
相关产品推荐

