Python语句:有时为真,有时为假。为什么?

3 投票
2 回答
663 浏览
提问于 2025-04-18 16:35

我想更好地理解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 个回答

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__这两个方法,但它们并不是< a href="https://docs.python.org/2/reference/datamodel.html" rel="nofollow">Python数据模型的一部分。你需要的是__le____ge__。如果这两个没有定义,Python会用__eq____lt__的组合来代替。通常情况下,这种组合在使用标准的代数定义<=时是逻辑上等价的,但在这个情况下……至少可以作为一个检查的地方。

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

撰写回答