为什么python中没有__max__的特殊方法?

时间:2018-03-14 07:52:36

标签: python

正如标题所要求的那样。 Python有很多特殊的方法,__add____len____contains__等。为什么在执行max时没有调用__max__方法?示例代码:

class A:
    def __max__():
        return 5

a = A()
max(a)

似乎range()和其他结构可以从中受益。我错过了其他一些有效的方法吗?¨

附录1: 作为一个简单的例子,max(range(1000000000))需要很长时间才能运行。

2 个答案:

答案 0 :(得分:3)

我没有权威的答案,但我可以提出我对这个问题的看法。

有几个内置函数没有相应的特殊方法。例如:

  • max
  • min
  • sum
  • all
  • any

他们有一个共同点是它们类似于reduce:它们遍历一个iterable并将其“减少”为一个值。这里的要点是,这些更像是一个组成部分。

例如,在应用迭代器之前,您经常将迭代器包装在生成器中(或其他理解或转换,如mapfilter):

sum(abs(val) for val in iterable)       # sum of absolutes
any(val > 10 for val in iterable)       # is one value over 10
max(person.age for person in iterable)  # the oldest person

这意味着大部分时间它甚至不会调用迭代的__max__,而是尝试在生成器上访问它(未实现且无法实现)。

如果这些措施得以实施,那么根本没有多大好处。在少数几种情况下实现它们是有意义的,如果你创建一个自定义方法(或属性)会更加明显,因为它突出显示它是一个“快捷方式”或者它与“正常结果”不同。

例如,这些函数(min等)具有O(n)运行时,因此如果您可以做得更好(例如,如果您有一个排序列表,则可以访问{{1}在max)中明确记录它可能是有意义的。

答案 1 :(得分:1)

某些操作不是基本操作。以max为例,它实际上是一种基于比较的操作。换句话说,当您获得最大值时,实际上您获得的是最大值。

所以在这种情况下,为什么我们应该实现指定的max函数但不能覆盖比较的行为?

从另一个方向思考,max到底意味着什么?例如,当我们执行max(list)时,我们在做什么?

我认为我们实际上正在检查list个元素,而max操作根本与list本身无关。

list只是max操作中不需要的容器。这是listset或其他内容,它并不重要。真正有用的是这个容器中的元素。

因此,如果我们为__max__定义list操作,我们实际上正在执行另一个完全不同的操作。我们要求容器给我们关于最大值的建议。

我认为在这种情况下,因为它是一个完全不同的操作,它应该是一个容器的方法,而不是覆盖内置函数的行为。