正如标题所要求的那样。 Python有很多特殊的方法,__add__
,__len__
,__contains__
等。为什么在执行max时没有调用__max__
方法?示例代码:
class A:
def __max__():
return 5
a = A()
max(a)
似乎range()
和其他结构可以从中受益。我错过了其他一些有效的方法吗?¨
附录1:
作为一个简单的例子,max(range(1000000000))
需要很长时间才能运行。
答案 0 :(得分:3)
我没有权威的答案,但我可以提出我对这个问题的看法。
有几个内置函数没有相应的特殊方法。例如:
max
min
sum
all
any
他们有一个共同点是它们类似于reduce:它们遍历一个iterable并将其“减少”为一个值。这里的要点是,这些更像是一个组成部分。
例如,在应用迭代器之前,您经常将迭代器包装在生成器中(或其他理解或转换,如map
或filter
):
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
操作中不需要的容器。这是list
或set
或其他内容,它并不重要。真正有用的是这个容器中的元素。
因此,如果我们为__max__
定义list
操作,我们实际上正在执行另一个完全不同的操作。我们要求容器给我们关于最大值的建议。
我认为在这种情况下,因为它是一个完全不同的操作,它应该是一个容器的方法,而不是覆盖内置函数的行为。