Reputation: 51
I have a class Parent
:
class Parent:
def __init__(self, foo):
self.foo = foo
I then have another class Child
which extends Parent
. But I want Child
to take a pre-existing instance of parent
and use this as the parent to inherit from (instead of creating a new instance of Parent
with the same constructor parameters).
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
Then I would ideally be able to do:
p = Parent("bar")
c = Child(p)
print(c.get_foo()) # prints "bar"
Upvotes: 5
Views: 2087
Reputation: 45
Using getattr()
to fetch the attribute from the parent instance
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
Upvotes: 0
Reputation: 894
I'm not sure inheritance is the right solution here as it breaks the LSP in the __init__
method.
Maybe parents and children just share a common interface. I'd prefer something like (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
The key point is that it takes advantage of polymorphism with a common interface FoeAware
, which is preferable to an inheritance tree.
Upvotes: 0
Reputation: 4507
You can use your own constructor - provide a classmethod that takes an instance of a parent.
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()
Upvotes: 3
Reputation: 2272
You could copy the content of the parents's __dict__
to the child's. You can use vars()
builtin function to do so, and the dictionary's update()
method.
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"
Upvotes: 8