Python3:为什么要自然而然地进行比较?
Python3: why the comparison is naturally made?
在下面的代码中,我在魔术方法 __lt__()
中定义了 '<',如果第一个参数小于第二个参数,它将 return True
return 否则为假。
from functools import total_ordering
@total_ordering
class Currency:
"""
One object of class Currency stores one amount of money, dollars and cents.
"""
def __add__(self, other):
"""
returns the result of adding self to other
"""
total = Currency(self.dollars, self.cents)
total.dollars = total.dollars + other.dollars
print (other.dollars)
total.cents = total.cents + other.cents
print (other.cents)
if total.cents > 100:
total.cents = total.cents - 100
total.dollars = total.dollars +1
return total
def __init__(self, dollars=0, cents=0):
self.dollars = dollars
self.cents = cents
def __str__(self):
return "$"+str(self.dollars)+"."+str(self.cents)
def __eq__(self, other):
return self.dollars==other.dollars and self.cents==other.cents
def __lt__(self, other):
if self.dollars<other.dollars:
return True
elif self.dollars > other.dollars:
return False
else: # dollars are equal
return self.cents < other.cents
然后我在测试程序中用'<'调用了__lt__()
。在这种情况下,candyPrice
(第一个参数)小于 bookPrice
(第二个参数),因此它按预期 returned True
。然后,我将这两个值与 class Currency
中未预定义的 '>' 进行比较,但它也按预期 returned False
。 所以我想知道是不是因为已经定义了__lt__()
,那么相反的表达式'>'表达式也被隐式定义了?
if __name__ == "__main__":
candyPrice = Currency (1, 17) # .17
bookPrice = Currency (12, 99) # .99
print (candyPrice < bookPrice)
print (candyPrice > bookPrice)
您使用了 @total_ordering
class 装饰器。这个装饰器显式地为你添加了其他方法。
来自@functools.total_ordering
documentation:
Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:
The class must define one of __lt__()
, __le__()
, __gt__()
, or __ge__()
. In addition, the class should supply an __eq__()
method.
所以即使您没有定义 __gt__
方法,class 装饰器已经使用您的 __lt__
方法为您定义了一个方法,连同 __eq__
。
例如,定义__lt__
方法时,__gt__()
实现设置为:
def _gt_from_lt(self, other, NotImplemented=NotImplemented):
'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
op_result = self.__lt__(other)
if op_result is NotImplemented:
return op_result
return not op_result and self != other
因此,如果 self < other
为假,则使用 self != other
。您没有定义 __ne__
方法,但您确实提供了 __eq__
并且 __ne__
的默认值为 return not self.__eq__(other)
;请参阅 object.__ne__()
documentation:
By default, __ne__()
delegates to __eq__()
and inverts the result unless it is NotImplemented
.
对于您的测试 Currency
个实例 __eq__
是不需要的,candyPrice.__gt__(bookPrice)
调用 candyPrice.__lt__(bookPrice)
,return 是正确的,因此 False
returned 没有检查 self != other
.
在下面的代码中,我在魔术方法 __lt__()
中定义了 '<',如果第一个参数小于第二个参数,它将 return True
return 否则为假。
from functools import total_ordering
@total_ordering
class Currency:
"""
One object of class Currency stores one amount of money, dollars and cents.
"""
def __add__(self, other):
"""
returns the result of adding self to other
"""
total = Currency(self.dollars, self.cents)
total.dollars = total.dollars + other.dollars
print (other.dollars)
total.cents = total.cents + other.cents
print (other.cents)
if total.cents > 100:
total.cents = total.cents - 100
total.dollars = total.dollars +1
return total
def __init__(self, dollars=0, cents=0):
self.dollars = dollars
self.cents = cents
def __str__(self):
return "$"+str(self.dollars)+"."+str(self.cents)
def __eq__(self, other):
return self.dollars==other.dollars and self.cents==other.cents
def __lt__(self, other):
if self.dollars<other.dollars:
return True
elif self.dollars > other.dollars:
return False
else: # dollars are equal
return self.cents < other.cents
然后我在测试程序中用'<'调用了__lt__()
。在这种情况下,candyPrice
(第一个参数)小于 bookPrice
(第二个参数),因此它按预期 returned True
。然后,我将这两个值与 class Currency
中未预定义的 '>' 进行比较,但它也按预期 returned False
。 所以我想知道是不是因为已经定义了__lt__()
,那么相反的表达式'>'表达式也被隐式定义了?
if __name__ == "__main__":
candyPrice = Currency (1, 17) # .17
bookPrice = Currency (12, 99) # .99
print (candyPrice < bookPrice)
print (candyPrice > bookPrice)
您使用了 @total_ordering
class 装饰器。这个装饰器显式地为你添加了其他方法。
来自@functools.total_ordering
documentation:
Given a class defining one or more rich comparison ordering methods, this class decorator supplies the rest. This simplifies the effort involved in specifying all of the possible rich comparison operations:
The class must define one of
__lt__()
,__le__()
,__gt__()
, or__ge__()
. In addition, the class should supply an__eq__()
method.
所以即使您没有定义 __gt__
方法,class 装饰器已经使用您的 __lt__
方法为您定义了一个方法,连同 __eq__
。
例如,定义__lt__
方法时,__gt__()
实现设置为:
def _gt_from_lt(self, other, NotImplemented=NotImplemented):
'Return a > b. Computed by @total_ordering from (not a < b) and (a != b).'
op_result = self.__lt__(other)
if op_result is NotImplemented:
return op_result
return not op_result and self != other
因此,如果 self < other
为假,则使用 self != other
。您没有定义 __ne__
方法,但您确实提供了 __eq__
并且 __ne__
的默认值为 return not self.__eq__(other)
;请参阅 object.__ne__()
documentation:
By default,
__ne__()
delegates to__eq__()
and inverts the result unless it isNotImplemented
.
对于您的测试 Currency
个实例 __eq__
是不需要的,candyPrice.__gt__(bookPrice)
调用 candyPrice.__lt__(bookPrice)
,return 是正确的,因此 False
returned 没有检查 self != other
.