什么时候应该直接调用__method__?

时间:2014-04-24 15:06:34

标签: python python-3.x methods

什么时候应该直接调用__dunder__方法?例如,而不是

a + b

可以写

a.__add__(b)

但这是一个好主意吗?

3 个答案:

答案 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__
    

一般而言,运营商更简单,更清晰。