python中的函数重载了吗?


91

Python中是否可能有重载函数?在C#中,我会做类似的事情

void myfunction (int first, string second)
{
//some code
}
void myfunction (int first, string second , float third)
{
//some different code
}

然后当我调用该函数时,它将根据参数的数量在两者之间进行区分。是否可以在Python中做类似的事情?


这似乎是重复的帖子。另外,请不要将其标记为C#,因为问题与C#无关。Python中的函数重载缺失
Jethro,


Answers:


103

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

通常,您不需要在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

3
但是请注意,根据参数的类型调用不同的函数要困难得多(尽管并非不可能)。
Andrew Jaffe

9
好吧,重载/多态和条件之间是有区别的。您的意思是因为有了条件,我们不需要多态吗?
2013年

1
@Val我基本上是说,在动态类型的语言中,您不需要将重载作为语言功能,因为您可以在代码中轻松地对其进行仿真,因此可以通过这种方式获得多态性。
2013年

1
@Val我说的是,在可选参数和动态类型之间,就像在Python中一样,您不需要Java样式方法重载即可实现多态。
13年

3
@navidoo我认为这不是一个好主意-函数不应返回完全不同类型的事物。但是,您始终可以在主函数内部定义本地生成器函数,调用它,然后返回生成的生成器-从外部看,它就像主函数是生成器一样。这里的例子。
2014年

50

在普通的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)检查参数和委托数量的函数。这种“ hack”通常是通过装饰器来完成的。在这种情况下,您可以实现以下目标:

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/


range内建使用过载,所以是不是真的一个黑客? github.com/python/typeshed/blob/master/stdlib/2and3/…–
CptJero

9

是的,有可能。我在下面的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根据未命名参数的数量选择要调用的函数。

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


1

无法直接进行。您可以对给定的参数使用显式类型检查,尽管通常对此并不满意。

Python是动态的。如果不确定对象可以做什么,只需尝试:并在其上调用方法,然后除外:错误。

如果您不需要基于类型而是仅根据参数数量进行重载,请使用关键字参数。


3
我认为他不了解可选参数。
2011年

0

重载方法在python中很棘手。但是,可能会使用传递字典,列表或原始变量的用法。

我已经为用例尝试过一些方法,这可以帮助您了解人们如何重载方法。

让我们以在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']}

因此,正在通过方法重载实现列表,字典或原始变量的处理。

试试看你的代码

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.