Python中的重载函数

106 投票
6 回答
118796 浏览
提问于 2025-04-16 23:54

在Python中可以有重载函数吗?

在C#中,我会这样做:

void myfunction (int first, string second)
{
    # Some code
}

void myfunction (int first, string second, float third)
{
    # Some different code
}

然后当我调用这个函数时,它会根据参数的数量来区分这两个函数。在Python中可以做类似的事情吗?

6 个回答

11

是的,这是可能的。我在Python 3.2.1中写了下面的代码:

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

使用方法:

myfunction=overload(no_arg_func, one_arg_func, two_arg_func)

请注意,overload函数返回的lambda表达式会根据传入的无名参数的数量来选择调用哪个函数。

这个解决方案并不是完美的,但目前我想不出更好的办法。

61

在普通的Python中,你无法直接实现你想要的功能。不过,有两种比较接近的方法:

def myfunction(first, second, *args):
    # 'args' is a tuple of extra arguments

def myfunction(first, second, third=None):
    # 'third' is optional

不过,如果你真的想这么做,当然可以实现(虽然可能会让一些传统派的人不高兴 ;o)。简单来说,你需要写一个叫做 wrapper(*args) 的函数,这个函数会检查传入的参数数量,然后根据情况进行处理。这种“黑科技”通常是通过装饰器来实现的。在这种情况下,你可以做到类似这样的效果:

from typing import overload

@overload
def myfunction(first):
    ....

@myfunction.overload
def myfunction(first, second):
    ....

@myfunction.overload
def myfunction(first, second, third):
    ....

你可以通过让 overload(first_fn) 这个函数(或者构造函数)返回一个可调用的对象来实现,里面的 __call__(*args) 方法 就是用来处理上面提到的参数分配,而 overload(another_fn) 方法 则是用来添加可以处理的额外功能。

你可以在这里看到类似的例子 http://acooke.org/pytyp/pytyp.spec.dispatch.html,不过那是通过类型来重载方法。这是一个非常相似的方法……

而且类似的功能(使用参数类型)正在被加入到Python 3中 - PEP 443 -- 单一分发通用函数

117

编辑 关于Python 3.4中新增加的单一分发通用函数,可以查看 这个链接

在Python中,通常不需要重载函数。因为Python是动态类型的,这意味着你可以在函数中使用可选参数。

def myfunction(first, second, third = None):
    if third is None:
        #just use first and second
    else:
        #use all three

myfunction(1, 2) # third will be None, so enter the 'if' clause
myfunction(3, 4, 5) # third isn't None, it's 5, so enter the 'else' clause

撰写回答