382 votes

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

J'ai une fonction Python qui prend plusieurs arguments. Certains de ces arguments peuvent ê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 d par le biais de h sont des chaînes de caractères qui ont chacune une signification différente. 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 ces éléments (ce sont mes choix).

Ce serait génial 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 non-concordance des arguments.

Pour l'instant, j'envoie des chaînes vides à la place des quelques premiers arguments manquants comme caractères de remplacement. J'aimerais pouvoir appeler une fonction en utilisant uniquement les valeurs réelles.

Y a-t-il un moyen de faire cela ? Pourrais-je passer une liste au lieu de la liste d'arguments ?

Actuellement, le prototype utilisant ctypes ressemble à quelque chose comme :

_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]

4 votes

Re W

1voto

Andrew Richards Points 61

Pour avoir une meilleure idée de ce qui est possible lors du passage de paramètres, il est très utile de se référer aux différentes options : positional-or-keyword ( arg o arg="default_value" ), positionnel uniquement (avant /, dans la liste des paramètres), mot-clé uniquement (après *, dans la liste des paramètres), var-positionnel (typiquement *args ) ou var-keyword (typiquement **kwargs ). Voir la documentation de Python pour une excellente résumé Les diverses autres réponses à la question utilisent la plupart de ces variations.

Puisque vous avez toujours les paramètres a, b, c dans votre exemple et que vous semblez les appeler de manière positionnelle, vous pourriez rendre cela plus explicite en ajoutant /, ,

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

1voto

wayne Points 1

Pour que la réponse d'Avión fonctionne pour les entrées de l'argument vectoriel ;

def test(M,v=None):
    try: 
        if (v==None).all() == False:
            print('argument passed')
            return M + v 
    except: 
        print('no argument passed')
        return M 

Où M est une matrice et v un vecteur. Test(M) et test(M,v) ont tous deux produit des erreurs lorsque j'ai tenté d'utiliser des instructions if sans utiliser les instructions 'try/ except'.

Comme mentionné par cem, la mise à jour vers python 3.10 permettrait la fonctionnalité union (x|y) (ou la fonctionnalité Optional[...]) qui pourrait ouvrir certaines portes pour des méthodes alternatives, mais j'utilise Anaconda spyder donc je pense que je dois attendre une nouvelle version pour utiliser python 3.10.

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