Python重載比較運算符


對象包含的內置方法

class MyObj(object):
    def __init__(self):
        self.value = 0


myObj = MyObj()
print(dir(myObj))

返回結果

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'value']

其中和對象比較的內置方法包括:

['__eq__', '__ge__', '__gt__', '__le__', '__lt__', '__ne__']

所以要重寫對象的比較規則,需要重寫這些比較方法。這樣寫很簡單,挨個實現就可以了。但是好事者高出了更吊的方法:@functools.total_ordering
源代碼如下:

_convert = {
    '__lt__': [('__gt__', _gt_from_lt),
               ('__le__', _le_from_lt),
               ('__ge__', _ge_from_lt)],
    '__le__': [('__ge__', _ge_from_le),
               ('__lt__', _lt_from_le),
               ('__gt__', _gt_from_le)],
    '__gt__': [('__lt__', _lt_from_gt),
               ('__ge__', _ge_from_gt),
               ('__le__', _le_from_gt)],
    '__ge__': [('__le__', _le_from_ge),
               ('__gt__', _gt_from_ge),
               ('__lt__', _lt_from_ge)]
}

def total_ordering(cls):
    """Class decorator that fills in missing ordering methods"""
    # Find user-defined comparisons (not those inherited from object).
    roots = [op for op in _convert if getattr(cls, op, None) is not getattr(object, op, None)]
    if not roots:
        raise ValueError('must define at least one ordering operation: < > <= >=')
    root = max(roots)       # prefer __lt__ to __le__ to __gt__ to __ge__
    for opname, opfunc in _convert[root]:
        if opname not in roots:
            opfunc.__name__ = opname
            setattr(cls, opname, opfunc)
    return cls

這樣一來,只要你在定義class的時候加上這個注解,再重寫運算符的時候,除了 __eq____ne__之外,其他的4個只需要重寫一個就可以了,@functools.total_ordering直接就幫你完成了其他比較方法的重寫。

@functools.total_ordering
class MyObj(object):
    def __init__(self):
        self.value = 0

    def __eq__(self, other):
        self


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM