我试图在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)

我该怎么做呢?


当前回答

Python 3.5增加了类型模块。这包括一个重载装饰器。

这个装饰器的目的是帮助类型检查器。功能上它只是鸭子打字。

from typing import Optional, overload


@overload
def foo(index: int) -> str:
    ...


@overload
def foo(name: str) -> str:
    ...


@overload
def foo(name: str, index: int) -> str:
    ...


def foo(name: Optional[str] = None, index: Optional[int] = None) -> str:
    return f"name: {name}, index: {index}"


foo(1)
foo("bar", 1)
foo("bar", None)

这将导致vs code中的以下类型信息:

虽然这可能有所帮助,但请注意,这添加了许多“奇怪的”新语法。它的目的——纯粹的类型提示——不是很明显。

使用类型的联合通常是更好的选择。

其他回答

我刚刚遇到了重载.py (Python 3的函数重载),有兴趣的同学可以去看看。

从链接库的README文件:

overloading is a module that provides function dispatching based on the types and number of runtime arguments. When an overloaded function is invoked, the dispatcher compares the supplied arguments to available function signatures and calls the implementation that provides the most accurate match. Features Function validation upon registration and detailed resolution rules guarantee a unique, well-defined outcome at runtime. Implements function resolution caching for great performance. Supports optional parameters (default values) in function signatures. Evaluates both positional and keyword arguments when resolving the best match. Supports fallback functions and execution of shared code. Supports argument polymorphism. Supports classes and inheritance, including classmethods and staticmethods.

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

class A:

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

在MathMethod.py文件中:

from multipledispatch import dispatch
@dispatch(int, int)
def Add(a, b):
   return a + b 
@dispatch(int, int, int)  
def Add(a, b, c):
   return a + b + c 
@dispatch(int, int, int, int)    
def Add(a, b, c, d):
   return a + b + c + d

在Main.py文件

import MathMethod as MM 
print(MM.Add(200, 1000, 1000, 200))

我们可以使用multipledispatch重载该方法。

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

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

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

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

我用Python 3.2.1写了我的答案。

def overload(*functions):
    return lambda *args, **kwargs: functions[len(args)](*args, **kwargs)

工作原理:

Overload接受任意数量的可调用对象,并将它们存储在元组函数中,然后返回lambda。 接受任意数量的参数, 然后返回存储在函数[number_of_unnamed_args_passed]中的调用函数的结果,并将参数传递给lambda。

用法:

class A:
    stackoverflow=overload(                    \
        None, \ 
        #there is always a self argument, so this should never get called
        lambda self: print('First method'),      \
        lambda self, i: print('Second method', i) \
    )