4

順序付けられたデータ型(範囲セット)で機能するデータ構造を実装するライブラリに取り組んでいます。正と負の無限大を考慮に入れると、多くの操作(反転など)が面白くなります。

1つの目標は、日時オブジェクトをこのモジュールで動作させることです。数値以外のオブジェクトで無限大をサポートするために、INFINITYとNEGATIVE_INFINITYを作成しました。

class _Indeterminate(object):
    def __eq__(self, other):
        return other is self

@functools.total_ordering
class _Infinity(_Indeterminate):
    def __lt__(self, other):
        return False
    def __gt__(self, other):
        return True
    def __str__(self):
        return 'inf'
    __repr__ = __str__

@functools.total_ordering
class _NegativeInfinity(_Indeterminate):
    def __lt__(self, other):
        return True
    def __gt__(self, other):
        return False
    def __str__(self):
        return '-inf'

INFINITY = _Infinity()
NEGATIVE_INFINITY = _NegativeInfinity()

残念ながら、cmp()操作の左側にある場合、これは日時オブジェクトでは機能しません。

In [1]: from rangeset import *
In [2]: from datetime import datetime
In [3]: now = datetime.now()
In [4]: cmp(INFINITY, now)
Out[4]: 1
In [5]: cmp(now, INFINITY)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/axiak/Documents/rangeset/<ipython-input-5-c928d3687d92> in <module>()
----> 1 cmp(now, INFINITY)

TypeError: can't compare datetime.datetime to _Infinity

オブジェクトが常に呼び出されるようにするcmpラッパーを使用することでこの制限を回避できることを望んでいましたが.sort()、これらのオブジェクト間でcmpが呼び出されるようにするメソッドを実際に使用したいと思います。

他のどのオブジェクトよりも本当に小さく、他のどのオブジェクトよりも本当に大きいオブジェクトを作成する方法はありますか?

モジュールホーム:https ://github.com/axiak/py-rangeset

4

3 に答える 3

5

ドキュメントから

比較がオブジェクトアドレスを比較するデフォルトのスキームにフォールバックするのを防ぐために、他の比較対象が日付オブジェクトでもない場合、日付比較は通常TypeErrorを発生させます。ただし、他の比較対象にtimetuple()属性がある場合は、代わりにNotImplementedが返されます。

timetupleしたがって、日時オブジェクトとの比較を可能にするには、メソッドを追加します。

class _Infinity(object):

    def __lt__(self, other):
        return False

    def __gt__(self, other):
        return True

    def timetuple(self):
        return tuple()

import datetime
INF = _Infinity()
now = datetime.datetime.now()
print cmp(INF, now)
print cmp(now, INF)

出力:

1    
-1
于 2011-12-08T18:32:03.010 に答える
0

よくわかりませんが、cmpを実行するたびに、上書き__eq__して__ne__(または)呼び出されるかどうかを確認してください。__cmp__また、cmpとpython3から削除されていることに注意する必要があります__cmp__

于 2011-12-08T17:45:54.050 に答える
0

問題は、datettimeクラスで直接定義されているcmp(now, INFINITY)ものと同等であるということです。datetime.__cmp__(INFINITY)dateetimeモジュールにモンキーパッチを適用することでこれを回避できますが、それは本当にハックです。

あなたが本当に望んでいるのは、クラスを考慮に入れ、無限の符号に応じて常にクラスを前後に配置するソート関数だと思います。

def order(x, y):
    if isinstance(x,_Infinity):
        return -1
    if isinstance(y, _Infinity):
        return 1
    elif isinstance(x, _NegativeInfinity):
        return 1
    elif isinstance(y, _NegativeInfinity):
         return -1
    else:
        return cmp(x,y)

>>> sorted([datetime.datetime.now(), datetime.datetime.now(), INFINITY, NEGATIVE_INFINITY], cmp=order)
[ 
    NEGATIVE_INFINITY, 
    datetime.datetime(2011, 12, 8, 13, 38, 47, 428626),
    datetime.datetime(2011, 12, 8, 13, 38, 47, 428661),
    INFINITY
]
于 2011-12-08T18:43:36.903 に答える