我想在Python中更好地理解OOP,并编写了一些描述(无限)序数算法的代码。我使用通常的比较运算符(Omega()
,==
等),添加和乘法定义了一个名为<=
的类。
我以为我会检查(应该是真的)添加到自身的第一个无限序数是否小于或等于第一个不可数序数。启动交互式shell,这是我发现的:
>>> a, b = Omega(), Omega(1)
>>> (a+a) <= b
False
>>> (a+a) <= b
True
>>> (a+a) <= b
False
相同的表达式产生不同的真值。
我继续测试表达式,无法发现任何模式。如果我重新解释代码,我发现重复测试表达式会产生不同的True
/ False
值序列。
可能导致此行为的原因是什么?
如果它相关,我在Windows 8.1上使用CPython 2.7.5。
这是我运行的Python代码:http://pastebin.com/XPqMphBw
答案 0 :(得分:6)
我认为您错误地重载了<=
和>=
运算符。而不是:
def __leq__(self, other):
# ...
def __geq__(self, other):
改为使用:
def __le__(self, other):
# ...
def __ge__(self, other):
进行这些更改并在Python 3.4.1中运行后,我得到:
>>> a, b = Omega(), Omega(1)
>>> (a+a) <= b
True
>>> (a+a) <= b
True
>>> (a+a) <= b
True
答案 1 :(得分:1)
与@Padraic Cunningham一样,我也无法复制您的问题(在Mac OS X上的Python 2.7.5下)。它给了我一致的答案。
您最好为对象提供一个易于理解的__repr__
方法,以便轻松打印它们以进行调试。例如:
def __repr__(self):
innards = ", ".join(str(v) for v in [self.index, self.power, self.copies])
return "{0}({1})".format(self.__class__.__name__, innards)
然后打印a
会显示Omega(0, 1, 1)
。一个稍微有点漂亮的版本可能是:
def __repr__(self):
innards = "index={index}, power={power}, copies={copies}".format(**self.__dict__)
return "{0}({1})".format(self.__class__.__name__, innards)
我还注意到你的代码可能不像你想象的那样计算“小于或等于”。您已定义方法__leq__
和__geq__
,但这些方法不属于Python data model。您希望(并且需要)__le__
和__ge__
代替。如果未定义,则会调用__eq__
和__lt__
的组合。如果你使用的是<=
的标准代数定义,那么这种组合通常具有逻辑等效性,但在这种情况下......它至少是一个要检查的地方。