一个带有标志或许多不同类的类

时间:2016-03-10 14:04:06

标签: python oop polymorphism

我陷入了两难境地。我正在制作数百种不同类型的物体。一般来说,它们将是Food,但主要是指定它是什么类型的食物。

class Food(object):
    def __init__(self, taste = None):
        self._taste = taste
class Bread(Food):pass
class Meat(Food):pass
class Soup(Food):pass

VS

class Food(object):
    def __init__(self, isbread = False, ismeat = False, issoup = False):
        self.is_bread = isbread
        self.is_meat = ismeat
        self.is_soup = issoup

然后我将比较那些对象,就像阵列中一个接一个地有两个面包一样。我想知道哪一个更符合OOP'的艺术,它可能更加pythonic。每次比较两个对象时,使用标志似乎比调用实例更快更容易。

2 个答案:

答案 0 :(得分:1)

使用不同的类是更多的OOP和Pythonic。使用gflags只是意味着存储关于类型以外的类型的信息。

现在有趣的部分是以一种方式处理类型信息,使代码具有可读性和清晰性以及良好的性能。说实话,我会忽略后者而不是好的代码,直到它成为一个问题。

由于使用该类型的唯一示例是比较对象是否为同一类型,因此您最容易做到这一点:

type(bread1) == type(bread2)

您还可以创建方法或重载运算符来隐藏代码的大多数部分的机制,但最简单和最易读的内容在很大程度上取决于您的实际用例。

再举一个你在讨论中提到的例子:要比较任何面包是否相等,你可以这样做:

class Bread(Food):
    def __eq__(self, other):
        return isinstance(other, Bread)

像这样明确地执行它允许您拥有子类Baguette(Bread)Roll(Bread),其实例(都是面包)也将比较相等,它们与Bread本身的任何实例相同。

答案 1 :(得分:0)

显然 第一个选项更加pythonic并且与OOP保持一致。

class Food(object):
    def __init__(self, taste = None):
        self._taste = taste
class Bread(Food):pass
class Meat(Food):pass
class Soup(Food):pass

这意味着所有SoupMeatBread对象都是Food,并且具有共同的属性。 那么,您希望比较两个对象是否属于Food的同一子类。只需使用isinstance()内置方法,然后检查是否True。例如,

>>> bread = Bread()
>>> soup = Soup()
>>> isinstance(bread, Soup)
False
>>> isinstance(bread, soup.__class__)
False
>>> isinstance(bread, Bread)
True

如果您想使用==运算符比较对象,只需覆盖__eq__(等于)方法即可。如下所示

class Food(object):

    def __init__(self, taste = None):
        self._taste = taste

    def __eq__(self, other):
        return (isinstance(other, self.__class__)

然后你比较像这样的对象

>>> bread1 = Bread()
>>> bread2 = Bread()
>>> soup = Soup()
>>> bread1 == soup
False
>>> bread1 == bread2 #Are both breads?
True