Python语句:有时是True,有时是False。为什么?

时间:2014-08-08 18:35:14

标签: python python-2.7 boolean behavior

我想在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

2 个答案:

答案 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__的组合。如果你使用的是<=的标准代数定义,那么这种组合通常具有逻辑等效性,但在这种情况下......它至少是一个要检查的地方。