私が理解していることから、のtotal_ordering
デコレータfunctools
は、順序付けられたクラスから継承されたクラスでうまく機能することが期待されていません.比較関数は既に定義されているため、定義しようとしません。
次の例を参照してください。
from functools import total_ordering
from collections import namedtuple
Test = namedtuple('Test',['a','b'])
@total_ordering
class TestOrd(Test):
def __lt__(self,other):
return self.b < other.b or self.b == other.b and self.a < other.a
x = TestOrd(a=1,b=2)
y = TestOrd(a=2,b=1)
print(x < y) # Expected: False
print(x <= y) # False
print(x > y) # True
print(x >= y) # True
print(y < x) # True
print(y <= x) # True
print(y > x) # False
print(y >= x) # False
<
すべてのテストの中で、オペレーターが関与するテストだけが期待される結果をもたらします。
クラス定義に>
追加することで、同様に機能させることができます。__gt__ = lambda *_ : NotImplemented
一方、__le__
orに同様の定義を追加すると__ge__
、対応するテストは (for __le__
) で失敗します。
TypeError: unorderable types: TestOrd() <= TestOrd()
これは、これが問題に対処する適切な方法ではないと私に信じさせます.
したがって、質問: total_ordering でクラスを並べ替える適切な方法はありますか?
(はい、私はtotal_ordering
の仕事を手作業で行うのは些細なことだと知っていますし、この例では unordered を定義することもnamedtuple
些細なことだと知っています。)