python - 覆盖python方法以返回具有扩展数据的正确类的对象
问题描述
假设我有一个 python 类,如:
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)
现在我想从这个类继承,添加一些数据:
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)
当然会发生这种情况:
>>> x = MealWithDessert("cake", "salad", "pizza")
salad pizza cake
>>> x.new_meal_eaten_starter()
eaten-salad pizza
当然我想看的是吃沙拉披萨蛋糕。我可以通过覆盖使用基本方法的方法来解决这个问题:
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
……但这太丑了。或者通过基本上复制基本方法(违反 DRY):
def new_meal_eaten_starter(self):
return MealWithDessert(self.dessert, "Eaten-%s" % self.starter, main=self.main)
...对于更复杂的功能,这两种选择都非常可怕。肯定有更好的方法吗?
解决方案
下面的代码片段实现了您打算做的事情,希望对您有所帮助
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)
推荐阅读
- ruby-on-rails - Rails:如何通过模型中的 id 通过关系创建 has_many?
- excel - Excel 2007 - 重新排列水平行中的垂直数据
- c# - 在循环内添加 SQL 参数,在循环外执行。(C# SQL 客户端中带参数的单查询多插入)
- angular - span 标签的测试用例
- d3.js - 如何在同一个图中使用 D3 创建不同类型的网格线
- sql-server - SQL IN 条件
- css - CSS网格:如何自动将所有列调整为最宽列?
- elasticsearch - 我可以在 Logstash 和 Elasticsearch 之间使用 Kafka 吗?(使用两个卡夫卡)
- css - 为什么一个小的 CSS 点在 Chrome 中没有相同的比例?
- python - 使用 tensorflow 执行标准化时出现错误 AttributeError: 'Node' object has no attribute 'output_masks'