我在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
t1
和t3
创建了两个实例,并为它们提供了不同的基数和高度,但它们的面积相等。因此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
>>>
答案 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
将为您提供该对象的物理地址。
在重新定义t1
,id(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())