使类支持比较操作
Posted jeffrey-yang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使类支持比较操作相关的知识,希望对你有一定的参考价值。
Python的基础数据类型大多支持比较操作,如 >=, ==, <=等。类对象默认不支持对象间比较操作,除非实现相应的__le__, __eq__, __le__方法等。
Python类可以通过为每个比较运算符实现一个特殊的方法来支持比较。 例如,要支持>=运算符,请在类中定义__ge __()方法。 尽管定义单个方法通常没有问题,但是创建每个可能的比较运算符的实现很快变得很繁琐。
Python模块functools提供了total_ordering类装饰器方法,可用于简化此过程。 要使用它,可以用它装饰一个类,并定义__eq ()和另一个比较方法(lt , le , gt__或__ge__)。 然后,装饰器填充其他未实现的比较方法。如下:
from functools import total_ordering
class Room:
def __init__(self, name, length, width):
self.name = name
self.length = length
self.width = width
self.square_feet = self.length * self.width
@total_ordering
class House:
def __init__(self, name, style):
self.name = name
self.style = style
self.rooms = list()
@property
def living_space_footage(self):
return sum(r.square_feet for r in self.rooms)
def add_room(self, room):
self.rooms.append(room)
def __str__(self):
return '{}: {} square foot {}'.format(self.name, self.living_space_footage, self.style)
def __eq__(self, other):
return self.living_space_footage == other.living_space_footage
def __lt__(self, other):
return self.living_space_footage < other.living_space_footage
# Build a few houses, and add rooms to them
h1 = House('h1', 'Cape')
h1.add_room(Room('Master Bedroom', 14, 21))
h1.add_room(Room('Living Room', 18, 20))
h1.add_room(Room('Kitchen', 12, 16))
h1.add_room(Room('Office', 12, 12))
h2 = House('h2', 'Ranch')
h2.add_room(Room('Master Bedroom', 14, 21))
h2.add_room(Room('Living Room', 18, 20))
h2.add_room(Room('Kitchen', 12, 16))
h3 = House('h3', 'Split')
h3.add_room(Room('Master Bedroom', 14, 21))
h3.add_room(Room('Living Room', 18, 20))
h3.add_room(Room('Office', 12, 16))
h3.add_room(Room('Kitchen', 15, 17))
houses = [h1, h2, h3]
print('Is h1 bigger than h2?', h1 > h2) # prints True
print('Is h2 smaller than h3?', h2 < h3) # prints True
print('Is h2 greater than or equal to h1?', h2 >= h1) # Prints False
print('Which one is biggest?', max(houses)) # Prints 'h3: 1101-square-foot Split'
print('Which is smallest?', min(houses)) # Prints 'h2: 846-square-foot Ranch'
如上所示,通过使用total_ordering,仅实现__eq__和__lt__,所有其他比较方法便自动实现。
如果编写了使类支持所有基本比较运算符的代码,那么total_ordering似乎并不是那么神奇:它从字面上定义了从每个比较支持方法到所有其他比较方法的映射。 因此,如果在解决方案中的类中定义了__lt __(),它将用于构建所有其他比较运算符。
class House:
def __eq__(self, other):
pass
def __lt__(self, other):
pass
# Methods created by @total_ordering
__le__ = lambda self, other: self < other or self == other
__gt__ = lambda self, other: not (self < other or self == other)
__ge__ = lambda self, other: not (self < other)
__ne__ = lambda self, other: not self == other
以上是关于使类支持比较操作的主要内容,如果未能解决你的问题,请参考以下文章