__eq__方法为==和>返回True运营商

时间:2017-03-11 15:55:13

标签: python comparison

我在Python中声明了一个类Triangle,它将base和height作为__init__个参数,并且有一个方法area来计算并返回三角形的区域。 __eq__类的Triangle方法比较三角形的面积并返回值。该课程定义如下:

class Shape(object):
    def area(self):
        raise AttributeException("Subclasses should override this method.")

class Triangle(Shape):
    def __init__(self, base, height):
        """
        base = base of the triangle.
        height = height of the triangle
        """
        self.base = base
        self.height = height
    def area(self):
        return (self.base * self.height)/2
    def __str__(self):
        return 'Triangle with base ' + str(self.base) + ' and height ' + str(self.height)
    def __eq__(self, other):
        """
        Two triangles are equal if their area is equal
        """
        return (self.area() == other.area())

现在我运行程序并为Triangle t1t3创建了两个实例,并为它们提供了不同的基数和高度,但它们的面积相等。因此t1 == t3应为True,仅作为True返回。但奇怪的是,t1 > t3也会以True的形式返回,我不明白为什么会这样做?

>>> t1 = Triangle(3,4)
>>> t3 = Triangle(2, 6)
>>> t1.area()
6
>>> t3.area()
6
>>> t1 == t3
True
>>> t1 > t3
True
>>> t1 < t3
False
>>> 

2 个答案:

答案 0 :(得分:3)

虽然我无法找到相应的来源,但如果您不自己定义相应的魔术方法,似乎Python 2使用id来比较两个对象。

观察:

>>> t1 = Triangle(3, 4)
>>> t3 = Triangle(2, 6)
>>> t1 > t3
False
>>> t1 < t3
True
>>> t1 = Triangle(3, 4)
>>> t1 > t3
True
>>> t1 < t3
False

这种行为并不能保证,因为id并不承诺为后来创建的对象分配越来越多的数字,但它通常似乎在CPython 2.7中起作用,因为id将为您提供该对象的物理地址。

在重新定义t1id(t1) < id(t3)之前,您会观察到这一点,之后情况恰恰相反。

答案 1 :(得分:2)

根据docs

  

如果没有定义__cmp __(),__ eq __()或__ne __()操作,则为   实例按对象标识(“地址”)进行比较。

this answer中也有说明,较新版本的python 2默认使用对象的id进行比较。

因此,您应始终在__gt__旁边定义__lt____eq__,以便比较您想要的方式。如果需要,您还可以定义__le____ge____ne__ ......

您可以改变的一件事是:

class Triangle(Shape):
    def __init__(self, base, height):
        """
        base = base of the triangle.
        height = height of the triangle
        """
        self.base = base
        self.height = height
    def area(self):
        return (self.base * self.height)/2
    def __str__(self):
        return 'Triangle with base ' + str(self.base) + ' and height ' + str(self.height)
    def __eq__(self, other):
        """
        Two triangles are equal if their area is equal
        """
        return (self.area() == other.area())
    def __gt__(self, other):
        """
        This works for both greater than and less than
        """
        return (self.area() > other.area())