使用相同的原理同时定义多种比较方法

问题描述 投票:0回答:1

我正在用 python 构建一个二叉树,将节点定义为一个类。我希望该节点具有一个值并且可以与其他节点进行比较,以便对它们的列表进行排序。

我想知道是否有一种更优雅的方法来避免显式定义所有比较方法(

__le__
__lt__
__eq__
)。我试过了,它有效:

class Node:
  def __init__(self, value, name=None, left=None, right=None):
    self.value=value
    self.name = name
    self.right, self.left = right, left
  
  def is_leaf(self):
    return self.right is None and self.left is None
  
  def __le__(self, other):
    return self.value.__le__(other.value) # or (self.value <= other.value)
  # same for __lt__, __eq__

但我想重用这些代码。更一般地说,我希望对象引用

self.value
来获取 dunder 方法列表,而不需要对每个方法进行显式编码。

我考虑强制从相同的基类继承,例如如果值是数字:

class Node(float)
,或者,在 init 中:

   def __init__(self, value, name=None, left=None, right=None):
     type(value).__init__(value)
     # etc.

但在我看来,它们是一种不好的做法,因为它们增加了许多潜在的意外行为。

当所有比较方法都遵守通用标准时,是否有一种Pythonic /优雅的方法来避免显式定义类中的所有比较方法?

python oop inheritance
1个回答
0
投票

IIUC,你可以使用

functools.total_ordering
:

from functools import total_ordering


@total_ordering
class Node:
    def __init__(self, value, name=None, left=None, right=None):
        self.value = value
        self.name = name
        self.right, self.left = right, left

    def is_leaf(self):
        return self.right is None and self.left is None

    def __le__(self, other):
        return self.value < other

    def __eq__(self, other):
        return self.value == other


n1 = Node(10)
n2 = Node(10)
n3 = Node(20)

print(f"{n1 < n2 = }")
print(f"{n1 > n2 = }")
print(f"{n1 == n2 = }")
print(f"{n1 < n3 = }")
print(f"{n1 > n3 = }")
print(f"{n1 > 5 = }")

打印:

n1 < n2 = False
n1 > n2 = False
n1 == n2 = True
n1 < n3 = True
n1 > n3 = False
n1 > 5 = True
© www.soinside.com 2019 - 2024. All rights reserved.