如何将子类转换为其父类?

How can I cast a child class to its parent?

提问人:Conor 提问时间:9/1/2022 更新时间:9/2/2022 访问量:656

问:

我有一个 Parent 类,并且我有一个额外的属性,我想临时存储在该父类上。Parent 类在我的代码之外使用,我不希望在那里使用我添加的属性。

我认为一个好的方法是创建一个子类,在那里添加我的属性,然后将该子类上抛到父类,删除我在代码中使用的任何属性。

这种方法似乎并不“pythonic”——而且没有简单的方法可以简单地将我的子类转换回父类。那么有没有其他方法可以做到这一点,或者有没有办法将这个子类转换回父级?

我放置了一些伪装代码,可以帮助您理解这些问题:

  • 我的代码库中使用了一些 Parent 方法(因此扩展 Parent 似乎是合适的)
  • Parent 的一个属性只能在末尾使用 my custom_arg Child 属性进行设置
  • 我认为 Parent 上的一种方法将所有属性转换为 json - 所以我不希望我在 Child 中设置的任何属性最终出现在那里。一旦我完成了子属性,我就可以删除它们,但这似乎很混乱,因为它仍然是“子”类型,但缺少子属性

因此,我能想到的最干净的解决方案是制作 Parent 类的干净副本,该类没有任何 Child 类方法或属性 - 但我还没有看到一个好的方法。我也愿意接受更好的建议。简单来说 - 我只需要在我的代码库中使用这个类时向它添加一个属性,然后在完成后将其删除。

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():
        ... does some stuff to set this attribute
    def to_json(self):
        return {... gets all attributes and puts them in attribute name: value form...}
    
class Child(Parent):
    def __init__(self, custom_arg, arg1, arg2):
        self.custom_arg
        self.super(arg1, arg2, arg_needs_to_be_set=None)
python-3.x 转换

评论

0赞 Mitchnoff 9/1/2022
您的父类不应该有子类属性有什么原因吗?
1赞 juanpa.arrivillaga 9/1/2022
“我认为一个好的方法是创建一个子类,在那里添加我的属性,然后将该子类上抛到父类,删除我在代码中使用的任何属性。”你说的“向上”是什么意思?这是python。它不是一种静态类型的语言,因此术语“upcast”实际上没有意义。

答:

0赞 mikb 9/2/2022 #1

我猜真正的问题是在不需要的时候在 json 对象中返回。Child.to_json()custom_arg

这不是你认为的问题,原因有两个。

  1. 如果 ,那么 ,所以如果你将一个实例传递给期望 实例的东西,它将正常工作isinstance(obj, Child) is Trueisinstance(obj, Parent) is TrueChildParent
  2. 在你的子项中,你可以重写父级中的方法,以提供你想要的行为,所以你专门过滤掉 - 任何在实例上调用 to_json() 方法的代码都会得到预期的结果to_json()self.custom_argchild

因此,要以python方式执行此操作:

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

    @property
    def attribute1(self):
        return self._attribute1

    @attribute1.setter
    def attribute1(self, *args, **kwargs):
        self._attribute1 = # whatever needs to be done, if it's funkier than just an expression

    def to_json(self):
        return json.dumps({k.lstrip("_"): v for k, v in vars(self).items()) # Or whatever else needs to be done

class Child(Parent):
    def __init__(self, custom_arg, arg1, arg2):
        super().__init__(arg1, None, arg2)
        self.custom_arg = custom_arg

    def to_json(self):
        return json.dumps({ k.lstrip("_"): v for k, v in vars(self).items() if k != "custom_arg"})

清澈如泥?