我想要的是用decorator 对两个物体进行比较.像这样的东西
@some_decorator
class SomeClass:
def __init__(self, value):
self.value = value
s1 = SomeClass(10)
s2 = SomeClass(5)
print(s1 > s2) # True
我知道魔法的方法.我只是好奇这真的可能还是不可能
我想要的是用decorator 对两个物体进行比较.像这样的东西
@some_decorator
class SomeClass:
def __init__(self, value):
self.value = value
s1 = SomeClass(10)
s2 = SomeClass(5)
print(s1 > s2) # True
我知道魔法的方法.我只是好奇这真的可能还是不可能
您可以在修饰器函数中定义一对比较函数,然后将它们添加到类中.要接受参数,可以对函数进行换行.使用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
正如@juanpa.arrivelaga在 comments 中建议的那样,这将判断实例,以便如下所示的比较按预期进行:
s1 > 50
# TypeError: '>' not supported between instances of 'SomeClass' and 'int'
而不是更令人困惑的:AttributeError: 'int' object has no attribute 'value'