如何从Python中预先存在的类实例继承?

2024-04-26 14:55:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个类Parent

class Parent:
    def __init__(self, foo):
        self.foo = foo

然后我有另一个类Child,它扩展了Parent。但是我希望Child获取一个预先存在的parent实例,并将其用作要从中继承的父实例(而不是使用相同的构造函数参数创建一个新的Parent实例)

class Child(Parent):
    def __init__(self, parent_instance):
        """ Do something with parent_instance to set this as the parent instance """

    def get_foo(self):
        return self.foo

那么我最好能做到:

p = Parent("bar")
c = Child(p)

print(c.get_foo()) # prints "bar"

Tags: 实例instanceselfchildgetfooinitdef
3条回答

您可以将父母的__dict__内容复制到孩子的。您可以使用vars()内置函数和字典的update()方法来执行此操作

class Child(Parent):
    def __init__(self, parent_instance):
        vars(self).update(vars(parent_instance))

    def get_foo(self):
        return self.foo


p = Parent("bar")
c = Child(p)

print(c.get_foo())
# prints "bar"

我不确定继承是否是正确的解决方案,因为它破坏了__init__方法中的LSP

也许父母和孩子只是共享一个共同的界面。 我更喜欢(Python3.8)这样的东西:

from typing import Protocol
    
class FoeAware(Protocol):
    @property
    def foe(self):
        ...
 
class Parent:
    def __init__(self, foe):
        self._foe = foe
   
    @property
    def foe(self):
        return self._foe

class Child:
    def __init__(self, parent: FoeAware):
        self.parent = parent

    @property
    def foe(self):
        return self.parent.foe

p = Parent("bar")
c = Child(p)
c.foe  # bar

关键的一点是,它利用了具有公共接口FoeAware的多态性,这比继承树更好

您可以使用自己的构造函数-提供一个类方法,该类方法接受父类的实例

class Parent:
    def __init__(self, foo):
        self.foo = foo

class Child(Parent):
    def get_foo(self):
        return self.foo

    @classmethod
    def from_parent(cls, parent_instance):
        return cls(parent_instance.foo)


p = Parent('bar')
c = Child.from_parent(p)
c.get_foo()

相关问题 更多 >