'Is it possible to inherit a parent class instance attribute directly into a child class instance in Python?
Here is the code that I have put together so far (and I understand why it does not work), but it illustrates what I am trying to achieve. First there is one parent class and multiple child classes (two shown) that inherit from the parent class:
class FruitClass(object):
def __init__(self,fruit):
self.fruit = fruit
def method(self):
print(f'{self.colour} {self.fruit}')
class Fruit1(FruitClass):
def __init__(self,colour):
self.colour = colour
class Fruit2(FruitClass):
def __init__(self,colour):
self.colour = colour
I then want to set the parent class attribute when instantiating the class and then use that specific attribute when calling parent class methods from the child classes. In the below example, I want to get fruit1.method()
to print out 'Green Apple'
. However, this is not working because the attribute is an attribute of the instance rather than the class itself. Is that correct? Further, I want to avoid having to pass in the attribute through the child function i.e. by instantiating the Fruit1
class instance with both 'Green'
and 'Apple'
parameters, since I have a lot of child classes and do not want to have to do this every time. Is this possible to do in a simple way?
fruit_class = FruitClass('Apple')
fruit1 = Fruit1('Green')
fruit2 = Fruit2('Red')
fruit1.method()
>>> AttributeError: 'Fruit1' object has no attribute 'fruit'
Update to better explain the use case here. I want a parent class with a method that the child classes can all access. But the variable in that method needs to vary depending on an external variable that I want to pass into the parent class. So my thought is to instantiate the parent class with that variable, thus affecting the way the method works and then instantiate all the classes relative to that specific parent class.
Other than that I guess an approach would be to create a completely separate parent class with a different method and store this in a separate module, but that would include all the same child classes as were deployed for the first module (and this feels like too much repitition). Plus then I would have to actively choose which module to import the child classes from when deploying the larger package (and I want to avoid that).
It is also specifically important that this variable be passed into the parent class, since it is not a simple choice of a or b. It will depend on what is happening in other areas of the package.
I hope that makes more sense.
Solution 1:[1]
It looks like you want a class factory.
def make_fruit_class(fruit):
class FruitClass:
def __init__(self, color):
self.fruit = fruit
self.color = color
def method(self):
print(f"{self.color} {self.fruit}")
return FruitClass
Then, you can create a class for any fruit like so:
BananaFruit = make_fruit_class("banana")
AppleFruit = make_fruit_class("apple")
And, you can instantiate objects of these classes:
yellow_banana = BananaFruit("yellow")
green_banana = BananaFruit("green")
red_apple = AppleFruit("red")
green_apple = AppleFruit("green")
And, call their methods:
yellow_banana.method() # yellow banana
green_banana.method() # green banana
red_apple.method() # red apple
green_apple.method() # green apple
Re.
Each child class has a variety of different init parameters, not just one colour parameter. It just to happens to be guaranteed that one common parameter amongst them
In this case, you could simply inherit from the class that was created by the factory.
class EdibleBanana(BananaFruit):
def __init__(self, color, who_can_eat):
super().__init__(color)
self.who_can_eat = who_can_eat
def info(self):
super().method()
print("Eaten by: ")
print("\t", self.who_can_eat)
class PoisonousBanana(BananaFruit):
def __init__(self, color, poisonous_to):
super().__init__(color)
self.poisonous_to = poisonous_to
def info(self):
super().method()
print("Poisonous to: ")
print("\t", self.poisonous_to)
class MagicalApple(AppleFruit):
def __init__(self, color, powers):
super().__init__(color)
self.powers = powers
def info(self):
super().method()
print("Magical powers: ")
print("\t", self.powers)
eb = EdibleBanana("yellow", ["humans", "monkeys", "chimps"])
pb = PoisonousBanana("green", ["snakes", "cats", "tigers"])
ma = MagicalApple("red", ["gives you wings", "makes you immortal"])
eb.info()
print("")
pb.info()
print("")
ma.info()
which gives:
yellow banana
Eaten by:
['humans', 'monkeys', 'chimps']
green banana
Poisonous to:
['snakes', 'cats', 'tigers']
red apple
Magical powers:
['gives you wings', 'makes you immortal']
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |