web-dev-qa-db-fra.com

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
}

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?

81
Trcx

[~ # ~] 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 les arguments optionnels des 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
96
agf

en normal python vous ne pouvez pas faire ce que vous voulez. Il y a deux approximations proches:

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

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

cependant, si vous vraiment voulez faire cela, vous pouvez certainement le faire fonctionner (au risque d'offenser les traditionalistes; o). En bref, vous écririez une fonction wrapper(*args) qui vérifie le nombre d'arguments et de délégués comme il convient. ce genre de "bidouille" se fait généralement via des décorateurs. dans ce cas, vous pourriez obtenir quelque chose comme:

from typing import overload

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

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

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

et vous implémenteriez ceci en faisant en sorte que la overload(first_fn) fonction (ou le constructeur) renvoie un objet appelable dans lequel la __call__(*args) méthode La délégation a-t-elle expliqué plus haut et la overload(another_fn) méthode ajoute-t-elle des fonctions supplémentaires pouvant ê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 il s’agit de surcharger les méthodes par type. c'est une approche très similaire ...

UPDATE: et quelque chose de similaire (en utilisant des types d’arguments) est ajouté à python 3 - http://www.python.org/dev/peps/pep-0443/ =

46
andrew cooke

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é.

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

7
GingerPlusPlus

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.

1
Jürgen Strobel

la surcharge des méthodes est délicate en python. Cependant, il pourrait être utilisé de passer les variables dict, list ou primitives.

J'ai essayé quelque chose pour mes cas d'utilisation, cela pourrait aider ici à comprendre les gens à surcharger les méthodes.

Prenons l'exemple de l'utilisation dans l'un des threads stackoverflow:

une méthode de surcharge de classe avec appel des méthodes de classe différente.

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

passer les arguments de la classe distante:

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

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

Ainsi, la manipulation est en cours pour les variables list, Dictionary ou primitives de la surcharge de méthode.

essayez-le pour vos codes

0
shashankS