Python中的重载函数
在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