【问题标题】:Minimum Methods for Ordering with Duck Typing in Python 3.1在 Python 3.1 中使用 Duck 类型进行排序的最少方法
【发布时间】:2012-04-07 13:35:21
【问题描述】:

the manual 中说:

一般来说,__lt__()__eq__() 就足够了,如果你想要 比较运算符的常规含义

但我看到了错误:

>       assert 2 < three
E       TypeError: unorderable types: int() < IntVar()

当我运行这个测试时:

from unittest import TestCase

class IntVar(object):

    def __init__(self, value=None):
        if value is not None: value = int(value)
        self.value = value

    def __int__(self):
        return self.value

    def __lt__(self, other):
        return self.value < other

    def __eq__(self, other):
        return self.value == other

    def __hash__(self):
        return hash(self.value)

class DynamicTest(TestCase):

    def test_lt(self):
        three = IntVar(3)
        assert three < 4
        assert 2 < three
        assert 3 == three

我很惊讶当IntVar() 在右边时,__int__() 没有被调用。我做错了什么?

添加 __gt__() 可以解决此问题,但这意味着我不明白订购的最低要求是什么...

谢谢, 安德鲁

【问题讨论】:

  • 如果你查看rich comparison method docs,它特别提到了这种行为——There are no swapped-argument versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, __lt__() and __gt__() are each other’s reflection, __le__() and __ge__() are each other’s reflection, and __eq__() and __ne__() are their own reflection. Arguments to rich comparison methods are never coerced.
  • @agf:答案应该在答案中,而不是在 cmets 中。
  • @EthanFurman 文档不会像 Sven 的回答那样具体案例,而且 IMO 有必要将其作为答案发布,而不仅仅是评论。

标签: python python-3.x duck-typing


【解决方案1】:

Python 3.x 永远不会对运算符进行任何类型强制,因此__int__() 不会在此上下文中使用。比较

a < b

将首先尝试调用type(a).__lt__(a, b),如果返回NotImplemented,它将调用type(b).__gt__(b, a)

文档中的引用是关于使比较适用于单一类型,上面的解释说明了为什么这对于单一类型就足够了。

要使您的类型与int 正确交互,您应该实现所有比较运算符,或者使用Python 2.7 或3.2 中可用的total_ordering decorator

【讨论】:

  • 谢谢。完全忘记了total_ordering。这样就完美了。
  • total_ordering 适用于您的情况。但是,两个使用 total_ordering 的不同类可能会出错:bugs.python.org/issue10042
猜你喜欢
  • 1970-01-01
  • 2011-06-21
  • 2013-07-07
  • 2016-08-30
  • 1970-01-01
  • 2017-12-26
  • 2017-11-04
  • 2018-11-02
  • 1970-01-01
相关资源
最近更新 更多