Comment créer une fonction Python avec des arguments facultatifs?

223

J'ai une fonction Python qui prend plusieurs arguments. Certains de ces arguments pourraient être omis dans certains scénarios.

def some_function (self, a, b, c, d = None, e = None, f = None, g = None, h = None):
    #code

Les arguments à dtravers hsont des chaînes qui ont chacune des significations différentes. Il est important que je puisse choisir les paramètres facultatifs à passer dans n'importe quelle combinaison. Par exemple,, (a, b, C, d, e)ou (a, b, C, g, h), ou (a, b, C, d, e, f, ou tous (ce sont mes choix).

Ce serait formidable si je pouvais surcharger la fonction - mais j'ai lu que Python ne prend pas en charge la surcharge. J'ai essayé d'insérer certains des arguments int requis dans la liste - et j'ai obtenu une erreur de discordance d'argument.

En ce moment, j'envoie des chaînes vides à la place des premiers arguments manquants en tant qu'espaces réservés. Je voudrais pouvoir appeler une fonction en utilisant simplement des valeurs réelles.

Y a-t-il un moyen de faire ça? Puis-je transmettre une liste au lieu de la liste d'arguments?

En ce moment, le prototype utilisant des ctypes ressemble à ceci:

_fdll.some_function.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]
Thalia
la source

Réponses:

198

Essayez d' appeler comme: obj.some_function( '1', 2, '3', g="foo", h="bar" ). Après les arguments positionnels requis, vous pouvez spécifier des arguments facultatifs spécifiques par nom.

Russell Borogove
la source
246

Utilisez simplement le *argsparamètre, qui vous permet de passer autant d'arguments que vous le souhaitez après votre a,b,c. Il faudrait ajouter de la logique à la carte args-> c,d,e,fmais c'est une "façon" de surcharger.

def myfunc(a,b, *args, **kwargs):
   for ar in args:
      print ar
myfunc(a,b,c,d,e,f)

Et il affichera les valeurs de c,d,e,f


De même, vous pouvez utiliser l' kwargsargument, puis vous pouvez nommer vos paramètres.

def myfunc(a,b, *args, **kwargs):
      c = kwargs.get('c', None)
      d = kwargs.get('d', None)
      #etc
myfunc(a,b, c='nick', d='dog', ...)

Et puis kwargsaurait un dictionnaire de tous les paramètres qui sont des valeurs clés aprèsa,b

Rien
la source
Je vous remercie. Bien que je ne puisse pas utiliser autant de flexibilité dans mon code, et cela ne résout pas mon problème d'appel avec divers trous vides dans ma liste, c'est un excellent outil à utiliser dans un projet différent. et Russel Borogove m'a donné la réponse exacte dont j'avais besoin pour mon problème, je suis heureux.
Thalia
12
Il s'appelle Listes d'arguments arbitraires
FabienB
@Nix, j'aime vraiment votre réponse. Cependant, pourriez-vous préciser à quoi c = kwargs.get('c', None)sert la déclaration ? Est-il requis dans toutes les fonctions qui ont des arguments optionnels? Dans votre code, vous n'aviez que 2 arguments optionnels. Et si l'utilisateur veut dire un autre argument e? Comment puis-je modifier votre exemple de code pour un nombre inconnu d'arguments optionnels, par exemple def my_func(a, b, *args, **kwagars): obj = <do something with a & b> obj.add(c) obj.add(d) continue obj.add(for e, f, g...):? Dois-je inclure c = kwargs.get('c', None) etcavant de faire le obj.add(c, d, ...)?
Nemo
Si vous êtes préoccupé par la complexité du temps. Ce serait un problème
NduJay