有没有办法在Python中使用装饰器在两个对象之间进行比较操作?

1 python class object decorator python-3.x

我想要的是用装饰器比较两个对象。像这样的东西

@some_decorator
class SomeClass:
    def __init__(self, value):
        self.value = value


s1 = SomeClass(10)
s2 = SomeClass(5)
print(s1 > s2)  # True
Run Code Online (Sandbox Code Playgroud)

我知道魔法方法。我只是好奇这真的可能吗

Mar*_*yer 6

您可以在装饰器函数中定义几个比较函数,然后将它们添加到类中。要接受参数,您可以包装该函数。使用functools.total_ordering是添加其他比较函数的便捷方法,无需将它们全部写出来(如果这很重要,请注意文档中有关性能的警告)。

from functools import total_ordering

def compare(attribute):
    def deco(klass):
        def __eq__(self, other):
            if isinstance(other, klass):
                return getattr(self, attribute) == getattr(other, attribute)
            else:
                return NotImplemented

        def __gt__(self, other):
            if isinstance(other, klass):
                return getattr(self, attribute) > getattr(other, attribute)
            else:
                return NotImplemented

        klass.__eq__ = __eq__ 
        klass.__gt__ = __gt__

        return total_ordering(klass)
    
    return deco

@compare('value')
class SomeClass():
    def __init__(self, value):
        self.value = value


s1 = SomeClass(10)
s2 = SomeClass(5)
print(s1 > s2)  # True
print(s1 >= s2)  # True
print(s1 < s2)  # False
print(s1 <= s2)  # False
print(s1 == s2) # False
print(s1 != s2) # True
Run Code Online (Sandbox Code Playgroud)

正如 @juanpa.arrivillaga 在评论中建议的那样,这会检查实例,以便像下面这样的比较按预期运行:

s1 > 50
# TypeError: '>' not supported between instances of 'SomeClass' and 'int'
Run Code Online (Sandbox Code Playgroud)

而不是更令人困惑的:AttributeError: 'int' object has no attribute 'value'