类的“启用”比较

时间:2011-04-28 20:12:16

标签: python class object

我想在我的CSC硬件上提供一些帮助。它位于类/对象上,它是一个关于定义圆的简单类,名称为Circle(object)。

HW的确切文本(我完成了这个hw的前两部分,因此第三部分是对初始问题的扩展):

“”“通过使用<,>,> =,< =,==和!=等运算符启用Circle对象的比较,在Circle类上展开,其中一个Circle被视为”更大“如果它实际上更大(即,有更大的面积)另一个圈子,那么就比另一个。”

以下代码:

A = Circle(2, 5, 1.5)
B = Circle(-6, 1, 1)
print A < B, A != B, A >= B

应生成此输出:

False True True

这是我显示圆圈坐标和半径的代码:

class Circle(object):
    def __init__(self, x=0, y=0, r=0):
        self.x = x
        self.y = y
        self.r = r
    def __str__(self):
        return "Circle at (%d , %d). Radius: %f" % (self.x, self.y, self.r)

def main():
    print Circle(3, 5, 4.0)

main()

这个类的输出是“Circle at(3,5).Radius:4:000000”

我们被指向了教科书的某个页面,其中包含类的数学运算符: eq (), gt (), ge (), lt (), le (), ne ()等 所以我在想,我的教授想要这样的东西吗?

import math
class Circle(object):
    def __init__(self, x=0, y=0, r=0):
        self.x = x
        self.y = y
        self.r = r
    def __str__(self):
        return "Circle at (%d , %d). Radius: %f" % (self.x, self.y, self.r)
    def calcArea(self, r):
        self.r = r
        return (math.pi)*(r**2)
    def __gt__(self, circ1Radius, circ2Radius)
        self.circ1Radius = circ1Radius
        self.circ2Radius = circ2Radius
        r1 = circ1Radius
        r2 = circ2Radius
        r1 > r2 or r2 > r1
    def __ge__(self, circ1Radius, circ2Radius)
    #And so on for __lt__(), __le__(), __ne__(), etc
def main():
    A = Circle(3,4,1.5) 
    B = Circle(1,2,5.0)
    C = Circle(5,7,7) 
    D = Circle(9,8,3)
    print A < B, B > C, A < C, A >= C
main()
#Output should be "True, False, True, False"

我们是否必须为要在类中使用的每个方法创建定义/属性?先感谢您。

4 个答案:

答案 0 :(得分:26)

您可以使用functools中的total_ordering decorator,如果您提供__eq__()和另一个,则会生成所有缺少的比较方法。

  

给定一个定义一个或多个的类   丰富的比较排序方法,这个   类装饰师提供其余的。   这简化了所涉及的工作   指定所有可能的富人   比较操作:

     

该类必须定义__lt__()之一,   __le__()__gt__()__ge__()。此外,班级应提供   __eq__()方法。

例如,

@total_ordering
class Student:
    def _is_valid_operand(self, other):
        return (hasattr(other, "lastname") and
                hasattr(other, "firstname"))
    def __eq__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) ==
                (other.lastname.lower(), other.firstname.lower()))
    def __lt__(self, other):
        if not self._is_valid_operand(other):
            return NotImplemented
        return ((self.lastname.lower(), self.firstname.lower()) <
                (other.lastname.lower(), other.firstname.lower()))

答案 1 :(得分:16)

定义或覆盖类的比较运算符。 http://docs.python.org/reference/expressions.html#notin

看起来你在正确的轨道上,除了你只需要将第二个圆形对象传递给你的比较。 self指的是第一个圆形对象。所以self.r会给你第一个圆圈的r。您还需要从方法中返回True或False。

def __gt__(self, circle2):
    return self.r > circle2.r

请注意,这只是比较圈子的r。

答案 2 :(得分:0)

这不是对您的问题本身的回应,但请注意,您的calcArea(...)方法实际上并不需要在类中。 (请注意,没有理由在其中使用self!)

事实上,你可能想要的是一个仍在类中的方法,如

def area(self):
   return math.pi*(self.r**2)

这样它实际上使用了你所在的圆的半径。

答案 3 :(得分:-1)

简短回答:是的。除非从基类继承此行为,否则必须定义要支持的比较运算符。