Python语句:有时为真,有时为假。为什么?
我想更好地理解Python中的面向对象编程(OOP),于是写了一些代码来描述(无限)序数运算。我定义了一个叫做Omega()
的类,并实现了常见的比较操作符(比如==
、<=
等),还有加法和乘法。
我想检查一下,第一个无限序数加上它自己,是否真的小于或等于第一个不可数序数。于是我打开了交互式命令行,结果发现了以下情况:
>>> 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
2 个回答
就像@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__
这两个方法,但它们并不是< a href="https://docs.python.org/2/reference/datamodel.html" rel="nofollow">Python数据模型的一部分。你需要的是__le__
和__ge__
。如果这两个没有定义,Python会用__eq__
和__lt__
的组合来代替。通常情况下,这种组合在使用标准的代数定义<=
时是逻辑上等价的,但在这个情况下……至少可以作为一个检查的地方。
我觉得你对 <=
和 >=
这两个操作符的重载做得不太对。你应该用下面这个:
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