什么时候应该直接调用__dunder__
方法?例如,而不是
a + b
可以写
a.__add__(b)
但这是一个好主意吗?
答案 0 :(得分:6)
总的来说,不,这不是一个好主意。毕竟操作员是有原因的,所以当使用操作员时,可以使用它。
有些事情直接调用特殊方法很有用。最常见的是子类化时。因此,当您覆盖特殊方法并且您也想调用超级方法时,您将不得不直接使用该名称。
除此之外,使用实际方法可以保留对它的引用,即x = a.__add__
。所以当你需要这样的东西时,你可以使用它。当然,对于基本运算符来说它也没那么有用,因为我们有operator
模块,它为运算符提供了二进制函数。
但可能存在一些边缘情况。一般情况下:如果您没有明确需要方法,请使用运算符。它更加清晰。
Martijn Pieters在评论中提到了另一个用例,即避免调用inverse运算符。如您所知,表达式a + b
将首先尝试调用a.__add__(b)
。如果返回特殊值NotImplemented
,或者换句话说,如果运算符未通过a
类型实现,则Python将尝试调用b.__radd__(a)
(如果{{1}是一个不同的类型)。因此,在您想要避免此行为的情况下,您可以直接调用b
- 此时您将获得a.__add__(b)
值。
答案 1 :(得分:1)
a.__add__(b)
是个好主意吗?
阅读更容易吗?可能不是。所以,通常不是一个好主意。
但是,有必要的一种情况是,当您编写子类并需要在父类上调用a方法时。
答案 2 :(得分:1)
是的!我可以想到一些用例:
链接到超类实现:
def __init__(self, ...):
super().__init__(self, ...)
调用超类实现以避免重写方法:
def __getattribute__(self, ...):
...
def foo(self, ...):
x = super().__getattribute__(self, 'bar')
当操作员不可用时调用dunder方法:
for scls in cls.__subclasses__():
...
Currying运营商:
mulByTen = (10).__mul__
一般而言,运营商更简单,更清晰。