Re 1、それは確かに私たちが設計した動作です-それが正しいか間違っているかはわかりません(それがあなたのユースケースをつまずかせたら申し訳ありませんが、私たちは一般的にしようとしていました!)。
具体的には、すべての Python オブジェクトが他のすべてのオブジェクトとの不等比較の対象となる可能性があるというケースが長い間ありました。実際には比較できない型のオブジェクトは、任意に比較されます (特定の実行で一貫して、必ずしも複数の実行にまたがる必要はありません)。主な使用例は、異種のリストをソートして、その中の要素をタイプ別にグループ化することでした。
複素数のみに例外が導入され、何にも匹敵しなくなりましたが、それはまだ何年も前のことであり、完全に優れたユーザーコードを壊すことについて時折無頓着でした. 最近では、メジャー リリース内での下位互換性についてはより厳密になっています (たとえば、2.*
ラインに沿って、または 1 つに沿って個別に、 2 と 3 の間の3.*
非互換性は許容されます。実際、それがシリーズを持つことの全体的なポイントであり、3.*
過去の設計を修正できます)。互換性のない方法でも決定します)。
恣意的な比較は、価値がある以上に面倒であることが判明し、ユーザーを混乱させました。タイプによるグループ化は、たとえば;へのkey=lambda x: str(type(x))
引数を使用して簡単に取得できるようになりました。sort
したがって、Python 3 では、オブジェクト自体が比較メソッドで明確に許可しない限り、異なるタイプのオブジェクト間の比較で例外が発生します。
>>> decimal.Decimal('2.0') > 1.2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Decimal() > float()
言い換えれば、Python 3 では、これはあなたが思っているとおりに動作します。しかし、Python 2 ではそうではありません (そして、どの Python でも決してそうなることはありません2.*
)。
Re 2 では問題ありませんが、gmpyを調べて、Farey 木を使用して double を無限精度の分数に変換する興味深い方法を探してください。扱っている価格がセント単位で正確な場合は、'%.2f' % x
ではなくrepr(x)
!-)を使用してください。
Decimal のサブクラスではなく、次のようなファクトリ関数を使用します。
def to_decimal(float_price):
return decimal.Decimal('%.2f' % float_price)
一度生成されると、結果の Decimal は完全に普通のものになるからです。