【问题标题】:Issues of choosing classmethod over inheritance in Python在 Python 中选择类方法而不是继承的问题
【发布时间】:2017-10-23 14:29:31
【问题描述】:

如果我选择在 Python 中使用 classmethod 而不是 Inheritance,我会遇到哪些主要问题?一个 (愚蠢的) 示例是:

class Pizza(object):
    def __init__(self, ingredients):
        self.ingredients = ingredients
        self.cooked = False

    def cook(self):        
        print "cooking"
        self.cooked = True

    # A pepperoni pizza using a factory method
    @classmethod
    def Pepperoni(cls):
        return cls("pepperoni")

# An onion pizza inheriting from Pizza base class
class Onion(Pizza):
    def __init__(self):
        ingredient = "onion"
        super(Onion, self).__init__(ingredient)

我知道

  • 我无法(轻松)向 Pepperoni 添加自定义方法
  • 我无法将 Pizza 设为抽象基类

还有什么?

【问题讨论】:

  • 披萨不就是在上面加了一些配料,为什么一定要抽象呢?意大利辣香肠披萨与洋葱披萨或加了意大利辣香肠的洋葱披萨有何不同?!
  • 即类方法与继承完全服务于不同的目的。
  • 请在比萨上了解技术,这只是一个例子
  • 好的,如果它们完全用于不同的目的,你能指出主要区别是什么吗?我可以创建一个Pizza.Pepperoni() 和一个Onion(),这两个对象将具有相同的方法和属性
  • 为什么类方法必须返回同一类的实例/类,这是完全错误的。你在这里取得了什么成就?

标签: python python-2.7 inheritance abstract-class class-method


【解决方案1】:

您似乎认为Pepperoni 本身就是一个类,就像Onion 一样。而Onion 是一个类,Pepperoni 只是一个基于Pizza 的函数。当然不应该将Pepperoni 视为一种正常的方法,但确实如此。 classmethod 装饰器有效地将 Pepperoni 方法转换为工厂函数,生成一个新实例。代码完全等同于只在类外写函数:

def Pepperoni():
    return Pizza("pepperoni")

您现在不会谈论“向Pepperoni 添加自定义方法”,但实际上什么都没有改变。

【讨论】:

  • 是的,我理解它们之间的区别,但我很难决定是应该使用继承还是只使用类方法。想象一下你必须编写 Pizza i> 对于一家拥有 30 种不同种类的商店,你会怎么做?
  • 我会简单地利用Pizzaingredients 参数:pizza_with_onion = Pizza('onion')。如果您需要以某种方式从比萨饼的配料以外的东西实例化比萨饼,则应该使用工厂函数。如果您还决定制作烤肉串,则需要一个全新的课程,这与比萨饼不同,但仍可能共享很多方法。
  • 谢谢伙计!我想制作一个工厂课程,虽然我不需要用比它的成分以外的东西实例化一个比萨饼并没有造成任何伤害 =)
猜你喜欢
  • 1970-01-01
  • 2017-07-22
  • 2017-03-15
  • 1970-01-01
  • 2022-01-11
  • 2010-10-30
  • 2019-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多