Suppose I have a python class like:
class Meal(object):
def __init__(self, starter, main="steak"):
self.starter = starter
self.main = main
def new_meal_eaten_starter(self):
return Meal("Eaten-%s" % self.starter, main=self.main)
def __repr__(self):
return "%s %s" % (self.starter, self.main)
Now I want to inherit from this class, adding some data:
class MealWithDessert(Meal):
def __init__(self, dessert, *args, **kwargs):
super().__init__(*args, **kwargs)
self.dessert = dessert
def __repr__(self):
return "%s %s %s" % (self.starter, self.main, self.dessert)
Of course this happens:
>>> x = MealWithDessert("cake", "salad", "pizza")
salad pizza cake
>>> x.new_meal_eaten_starter()
eaten-salad pizza
Of course what I want to see was eaten-salad pizza cake. I can solve this problem by overriding the method to use the base method:
def new_meal_eaten_starter(self):
new_meal_no_dessert = super().new_eaten_starter()
new_meal = MealWithDessert(self.dessert, new_meal_no_dessert.starter, main=new_meal_no_dessert.main)
return new_meal
... but that is dammn ugly. Or by basically copying the base method (which violates DRY):
def new_meal_eaten_starter(self):
return MealWithDessert(self.dessert, "Eaten-%s" % self.starter, main=self.main)
... and for more complex functions both options are really horrific. Surely there must be a better way?
The snippet below achieved what you intend to do, I hope it helps
class Meal(object):
def __init__(self, starter, main="steak"):
self.starter = starter
self.main = main
def new_meal_same_starter(self, new_main):
meal_class = globals()[self.__class__.__name__]
new_args = self.__dict__.copy()
new_args['starter'] = "Eaten-%s" % new_args['starter']
new_args['main'] = new_main
return meal_class(**new_args)
def __repr__(self):
return "%s %s" % (self.starter, self.main)
class MealWithDessert(Meal):
def __init__(self, dessert, *args, **kwargs):
super(MealWithDessert, self).__init__(*args, **kwargs)
self.dessert = dessert
def __repr__(self):
return "%s %s %s" % (self.starter, self.main, self.dessert)
x = MealWithDessert("cake", "salad", "pizza")
print(x)
y = x.new_meal_same_starter("tofu")
a = Meal("Rice")
b = a.new_meal_same_starter("Bread")
print(a)
print(b)
print(y)
print(x)
I think problem here is following method in class meal
def new_meal_same_starter(self, new_main):
return Meal(self.starter, main=new_main)
You just need to update the main with new_main meal. So Try this:
def new_meal_same_starter(self, new_main):
self.main=new_main
If you need to return from the method, then override it:
def new_meal_same_starter(self, new_main):
return MealWithDessert(self.dessert, self.starter, main=new_main)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.