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

我该怎么做呢?


当前回答

你也可以使用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)

其他回答

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

你不能,永远不需要,也不想这么做。

在Python中,所有东西都是对象。类是事物,所以它们是对象。方法也是如此。

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

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

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

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

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

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

你也可以使用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)

在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重载该方法。

我用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