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

如何从Python中预先存在的类实例继承?,python,python-3.x,oop,inheritance,Python,Python 3.x,Oop,Inheritance,我有一个班级家长: 类父级: 定义初始化(self,foo): self.foo=foo 然后我有另一个类Child,它扩展了Parent。但是我希望Child获取一个预先存在的parent实例,并将其用作要从中继承的父实例(而不是使用相同的构造函数参数创建一个新的parent实例) 类子级(父级): def uuu init uuu(self,parent_实例): “”“对父实例执行某些操作以将其设置为父实例”“” def get_foo(自我): return self.foo 那么我

我有一个班级
家长

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

类子级(父级):
def uuu init uuu(self,parent_实例):
“”“对父实例执行某些操作以将其设置为父实例”“”
def get_foo(自我):
return self.foo
那么我最好能做到:

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

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

您可以将家长的
\uuuu dict\uuuu
内容复制到孩子的。您可以使用
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"

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

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()
使用
getattr()
从父实例获取属性

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

class Child(Parent): 
    def __init__(self, parent_instance): 
        self.parent_instance = parent_instance
    
    def get_foo(self): 
        return self.foo 
        
    def __getattr__(self, attr):
        return getattr(self.parent_instance, attr)

par = Parent("bar") 
ch = Child(par)
print(ch.get_foo())
#prints bar

我不确定继承在这里是否是正确的解决方案,因为它打破了
\uuuu init\uuuu
方法中的限制

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"
也许父母和孩子只是共享一个共同的界面。 我更喜欢(蟒蛇3.8)这样的东西:

来自输入导入协议
类别识别(协议):
@财产
def敌人(自身):
...
类父级:
定义初始(自我,敌人):
自我。_敌人=敌人
@财产
def敌人(自身):
回归自我
班级儿童:
def uuu init uuuu(自我,父级:FoeAware):
self.parent=parent
@财产
def敌人(自身):
返回self.parent.foe
p=母公司(“bar”)
c=儿童(p)
c、 福巴

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

self.parent=parent\u instance
,然后是
self.parent.foo
或类似的东西?@klauds。可以,但如果可能的话,我更喜欢正确的继承。目前,您的建议就是我正在做的。这是一个古老问题的重复:建议仍然有意义:)在您的示例中,
“bar”
只能获得实例属性。但您只能继承类属性。但这将创建父级的新实例,对吗?我不想重新实例化。如果在父类中更改了foo属性,则链接将在子类中中断。(孩子将保留较老的参考资料)例如:p=父母(“foo”);c=来自父母的子女(p);p、 foo=“垃圾邮件”;断言c.foo==“foo”这有什么缺点吗?没有,除非您不希望子对象具有父对象所具有的某些特定属性。我认为这将创建一个新的
parent
实例-我希望使用已传入的
parent
的现有实例。如果在父对象实例中附加另一个不在init中的属性,这将崩溃签名。或者,如果实例属性被重命名,例如
self.\u foo=foo
我已经更新了代码,以便在不创建其他实例的情况下工作