在python中重载函数?

Overloaded functions in python?

是否可以在python中重载函数?在C我会做一些像

1
2
3
4
5
6
7
8
void myfunction (int first, string second)
{
//some code
}
void myfunction (int first, string second , float third)
{
//some different code
}

然后,当我调用函数时,它会根据参数的数量区分这两个函数。是否可以在Python中执行类似的操作?


在python 3.4中编辑新的单调度通用函数,请参见http://www.python.org/dev/peps/pep-0443/

通常不需要在Python中重载函数。python是动态类型的,支持函数的可选参数。

1
2
3
4
5
6
7
8
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


在普通的python中,你不能做你想做的。有两个近似值:

1
2
3
4
5
def myfunction(first, second, *args):
    # args is a tuple of extra arguments

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

然而,如果你真的想这样做,你当然可以让它工作(冒着冒犯传统主义者的风险;o)。简而言之,您将编写一个wrapper(*args)函数,检查参数和委托的数量(如果合适)。这种"黑客"通常是通过装饰工完成的。在这种情况下,您可以实现如下目标:

1
2
3
4
5
6
7
8
9
10
11
12
13
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中-http://www.python.org/dev/peps/pep-0443/


是的,这是可能的。我在python 3.2.1中编写了以下代码:

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

用途:

1
myfunction=overload(no_arg_func, one_arg_func, two_arg_func)

注意,overload函数返回的lambda根据未命名参数的数量选择要调用的函数。

解决方案并不完美,但目前我写不出更好的东西。


不能直接进行。但是,您可以对给定的参数使用显式类型检查,尽管这通常是不允许的。

python是动态的。如果您不确定对象可以做什么,只需尝试:并对其调用一个方法,然后except:errors。

如果您不需要基于类型重载,而只需要根据参数个数重载,请使用关键字参数。


在Python中,重载方法是很棘手的。但是,也可以使用传递dict、list或基元变量。

我已经为我的用例做了一些尝试,这有助于理解人们过载的方法。

让我们以其中一个stackoverflow线程中使用的示例为例:

具有从不同类调用方法的类重载方法。

def add_bullet(sprite=None, start=None, headto=None, spead=None, acceleration=None):

从远程类传递参数:

add_bullet(sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},accelaration=10.6}

add_bullet(sprite = 'test', start=Yes,headto={'lat':10.6666,'long':10.6666},speed=['10','20,'30']}

因此,正在通过方法重载对列表、字典或基元变量进行处理。

试试看你的密码