97 votes

Fonctions surchargées en python?

Est-il possible d'avoir des fonctions surchargées en Python? En C #, je ferais quelque chose comme

 void myfunction (int first, string second)
{
//some code
}
void myfunction (int first, string second , float third)
{
//some different code
}
// This maybe a little off, I haven't coded C# in a couple years
 

et ensuite, lorsque j'appelle la fonction, elle différencie les deux en fonction du nombre d'arguments. Est-il possible de faire quelque chose de similaire en Python?

108voto

agf Points 45052

EDIT Pour les nouvelles fonctions génériques de dispatch unique dans Python 3.4, voir http://www.python.org/dev/peps/pep-0443/

Vous n'avez généralement pas besoin de surcharger les fonctions en Python. Python est typé dynamiquement et supporte des arguments optionnels pour les fonctions.

 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
 

54voto

andrew cooke Points 20902

normal python que vous ne pouvez pas faire ce que vous voulez. il y a deux notions proches:

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

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

toutefois, si vous vraiment voulez faire cela, vous pouvez certainement le faire fonctionner (au risque de choquer les traditionalistes ;o). en bref, vous devez écrire un wrapper(*args) fonction qui vérifie le nombre d'arguments et de délégués, selon le cas. ce genre de "hack" se fait généralement via des décorateurs. dans ce cas, vous pourriez obtenir quelque chose comme:

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

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

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

et vous mettriez en faisant de l' overload(first_fn) de la fonction (ou le constructeur) renvoient un objet appelable où l' __call__(*args) méthode de la délégation a expliqué ci-dessus et l' overload(another_fn) méthode ajoute des fonctions supplémentaires qui peuvent être déléguées.

vous pouvez voir un exemple de quelque chose de similaire ici http://acooke.org/pytyp/pytyp.spec.dispatch.html mais c'est la surcharge de méthodes par type. c'est une approche très semblable...

Mise à JOUR: et quelque chose de similaire (à l'aide de types d'argument) est ajoutée à python 3 - http://www.python.org/dev/peps/pep-0443/

10voto

GingerPlusPlus Points 851

Oui c'est possible. J'ai écrit le code ci-dessous dans Python 3.2.1:

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

Usage:

 myfunction=overload(no_arg_func, one_arg_func, two_arg_func)
 

Notez que le lambda renvoyé par les fonctions overload choisit la fonction à appeler en fonction du nombre d'arguments non nommés .

La solution n'est pas parfaite, mais pour le moment, je ne peux rien écrire de mieux.

1voto

Jürgen Strobel Points 1365

Pas possible directement. Vous pouvez utiliser des contrôles de type explicites sur les arguments donnés, bien que cela soit généralement mal vu.

Python est dynamique. Si vous n'êtes pas sûr de ce qu'un objet peut faire, essayez simplement: et appelez une méthode dessus, sauf: errors.

Si vous n'avez pas besoin de surcharger en fonction des types, mais uniquement du nombre d'arguments, utilisez des arguments de mots clés.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X