zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    read()系统调用的流程(转个贴)
    linux kernel reading
    开博第一篇
    让人崩溃的Visual C++ 2005 SP1 Redistributable Package (x86),为啥我下不下来?
    System Call on Linux 2.6 for i386(2) int 0x80与systementer
    http://www.netyi.net/in.asp?id=yuanxianping
    取Insert产生的ID
    递归触发器资料
    Commit Trans和Rollback Trans在有触发器操作时的区别
    转:安全配置SQL Server2000服务器
  • 原文地址:https://www.cnblogs.com/byron0918/p/10209341.html
Copyright © 2011-2022 走看看