我试图在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 2.7写了我的答案:

在Python中,方法重载是不可能的;如果你真的想用不同的特性访问同一个函数,我建议你使用方法重写。

class Base(): # Base class
    '''def add(self,a,b):
        s=a+b
        print s'''

    def add(self,a,b,c):
        self.a=a
        self.b=b
        self.c=c

        sum =a+b+c
        print sum

class Derived(Base): # Derived class
    def add(self,a,b): # overriding method
        sum=a+b
        print sum



add_fun_1=Base() #instance creation for Base class
add_fun_2=Derived()#instance creation for Derived class

add_fun_1.add(4,2,5) # function with 3 arguments
add_fun_2.add(4,2)   # function with 2 arguments

其他回答

你也可以使用pythonlangutil:

from pythonlangutil.overload import Overload, signature

class A:
    @Overload
    @signature()
    def stackoverflow(self):    
        print('first method')
    
    @stackoverflow.overload
    @signature("int")
    def stackoverflow(self, i):
        print('second method', i)

我刚刚遇到了重载.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中,所有东西都是对象。类是事物,所以它们是对象。方法也是如此。

有一个对象叫做A,它是一个类。它有一个名为stackoverflow的属性。它只能有一个这样的属性。

当你写def stackoverflow(…):…,所发生的是你创建一个对象,它是方法,并将它赋值给a的stackoverflow属性。如果你写了两个定义,第二个会替换第一个,这与赋值的行为相同。

此外,您也不希望编写的代码执行重载有时会用到的那种过分的操作。语言不是这样的。

与其尝试为可能给定的每种类型的东西定义一个单独的函数(这没什么意义,因为你没有为函数参数指定类型),不如停止担心这些东西是什么,开始思考它们能做什么。

您不仅不能单独编写一个来处理元组和列表,而且也不想或不需要这样做。

你所要做的就是利用它们都是可迭代的这一事实,例如,你可以写for element in container:)。(他们之间没有直接的遗传关系,这一点无关紧要。)

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

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

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

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

Python在PEP-3124中添加了@overload装饰器,为通过类型检查进行重载提供语法糖——而不仅仅是使用重写。

关于通过PEP-3124中的@overload重载的代码示例

from overloading import overload
from collections import Iterable

def flatten(ob):
    """Flatten an object to its component iterables"""
    yield ob

@overload
def flatten(ob: Iterable):
    for o in ob:
        for ob in flatten(o):
            yield ob

@overload
def flatten(ob: basestring):
    yield ob

由@overload-decorator转换为:

def flatten(ob):
    if isinstance(ob, basestring) or not isinstance(ob, Iterable):
        yield ob
    else:
        for o in ob:
            for ob in flatten(o):
                yield ob