我试图在Python中实现方法重载:

class A:
    def stackoverflow(self):    
        print 'first method'
    def stackoverflow(self, i):
        print 'second method', i

ob=A()
ob.stackoverflow(2)

但是输出是第二种方法2;类似的:

class A:
    def stackoverflow(self):    
        print 'first method'
    def stackoverflow(self, i):
        print 'second method', i

ob=A()
ob.stackoverflow()

给了

Traceback (most recent call last):
  File "my.py", line 9, in <module>
    ob.stackoverflow()
TypeError: stackoverflow() takes exactly 2 arguments (1 given)

我该怎么做呢?


当前回答

有一些库可以简化这个过程:

Functools -如果你只需要第一个参数,使用@singledispatch

李子调度-功能丰富的方法/函数重载。

多调度-替代梅花少功能,但轻量级。

其他回答

在3.4之前,agf的答案是正确的,而现在有了PEP-3124,我们得到了语法糖。

有关@overload装饰器的详细信息,请参阅typing文档,但请注意,这真的只是语法糖,恕我冒犯,这是人们一直在争论的问题。

就我个人而言,我同意拥有多个具有不同签名的函数比拥有一个具有20多个参数都设置为默认值(大多数时候没有)的单一函数更具可读性,然后不得不使用无休止的if, elif, else链来找出调用者实际希望我们的函数对所提供的参数集做什么。在Python禅之后,这是早就该有的:

美总比丑好。

也可以说

简单比复杂好。

直接来自上面链接的Python官方文档:

from typing import overload
@overload
def process(response: None) -> None:
    ...
@overload
def process(response: int) -> Tuple[int, str]:
    ...
@overload
def process(response: bytes) -> str:
    ...
def process(response):
    <actual implementation>

编辑:如果有人想知道为什么这个例子不能像你从其他语言中期望的那样工作,我建议看看这个讨论。@overloaded函数不应该有任何实际的实现。这在Python文档中的示例中并不明显。

有一些库可以简化这个过程:

Functools -如果你只需要第一个参数,使用@singledispatch

李子调度-功能丰富的方法/函数重载。

多调度-替代梅花少功能,但轻量级。

我想你想说的是"超载"Python中没有任何方法重载。但是,您可以使用默认参数,如下所示。

def stackoverflow(self, i=None):
    if i != None:
        print 'second method', i
    else:
        print 'first method'

当您向它传递一个参数时,它将遵循第一个条件的逻辑并执行第一个print语句。当你不给它传递参数时,它将进入else条件并执行第二个print语句。

在Python中,您可以使用默认参数来完成此操作。

class A:

    def stackoverflow(self, i=None):    
        if i == None:
            print 'first method'
        else:
            print 'second method',i

Python 3。X包含标准类型库,允许使用@overload装饰器进行方法重载。不幸的是,这是为了使代码更具可读性,因为@overload装饰方法之后需要跟随一个处理不同参数的非装饰方法。 除了你的例子,你可以在这里找到更多:

from typing import overload
from typing import Any, Optional
class A(object):
    @overload
    def stackoverflow(self) -> None:    
        print('first method')
    @overload
    def stackoverflow(self, i: Any) -> None:
        print('second method', i)
    def stackoverflow(self, i: Optional[Any] = None) -> None:
        if not i:
            print('first method')
        else:
            print('second method', i)

ob=A()
ob.stackoverflow(2)