IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Avoir de multiples '*args, **kwargs' est-il possible dans une fonction ?


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Points : 5
    Points
    5
    Par défaut Avoir de multiples '*args, **kwargs' est-il possible dans une fonction ?
    On connaît le schéma classique pour passer des arguments:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def f(*args, **kwargs):
         <du code>
    Mais je voudrais utiliser une méthode comme ci-dessous, le nombre "n" de tuples variant de 0 à un nombre maximal fixé dans mon application:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    def f((*args_1, **kwargs_1), (*args_2, **kwargs_2), ... , (*args_n, **kwargs_n), **kwargs)
        <du code>
    Pour produire ce type d'appel :

    foo((20, 30, a='xx', b='yy'), (50, 60, 20, a='ww'), globalparam='zz')

    A priori c'est impossible, mais est-ce (raisonnablement) contournable ? Merci.

  2. #2
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Bonjour,

    Ton code semble tout à fait faisable, car tu regroupes les différents args/kwargs dans des tuples, ce qui permet de les identifier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def foo(*a,**k): % chaque tuple dans *a <=> (*a(n),**k(n))
        all_a= [aa[0] for aa in a] % tous les args
        all_k= [aa[1] for aa in a]% tous les kwargs

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Points : 5
    Points
    5
    Par défaut
    Malheureusement ça ne semble pas fonctionner. Copier le dernier exemple que je donne avec "foo", par exemple.

  4. #4
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir,

    Avec l’assignation dans le tuple difficile...
    Sinon pourquoi ne pas utiliser des dico ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def foo(*a, **k):
        pass
    foo((20, 30, {'a':'xx'}, {'b':'yy'}), (50, 60, 20, {'c':'ww'}), globalparam='zz')
    @+
    Merci d'utiliser le forum pour les questions techniques.

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Points : 5
    Points
    5
    Par défaut
    Je précise le contexte. En fait j'écris un programme avec une interface dans lequel l'utilisateur manipule et créer des objets, disons "Bar" pour l'exemple. Pour une question d'ergonomie, j'aimerais beaucoup que l'initialisation puisse se faire comme je l'indique, dans mon cas réel il y aura beaucoup de paramètres, or cette forme est très expressive et me semble la meilleure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    class Bar:
     
        def __init__(self, *args, **kwargs)
            <code>
            self.__foo(args, kargs)
            <code>
     
        def __foo(self, *args, **kwargs)
            <code>
    invite de commande :
    my_bar = Bar((20, 30, a='xx', b='yy'), (50, 60, 20, a='ww'), globalparam='zz')

    J'aimerais que l'utilisateur n'ai pas à créer des objets intermédiaires (des dictionnaires par exemple).

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    14
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 14
    Points : 5
    Points
    5
    Par défaut
    @PauseKawa

    Le meilleur compromis possible semble celui que vous proposez : utiliser des dictionnaires anonymes incorporés dans les n tuples.

    Merci.

  7. #7
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je ne sais pas si le problème posé par le 1er message existe toujours, mais voilà une solution possible (Python 2.7):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    def f1(*args, **kwargs):
        print "appel de f1"
        for arg in args:
            print arg
        for key in kwargs:
            print key, "=>", kwargs[key], {key:kwargs[key]}
     
    def f2(x, y, z, c=0):
        print "appel de f2"
        print x
        print y
        print z
        print c
     
    def f((args1, kwargs1), (args2, kwargs2)):
        f1(*args1, **kwargs1)
        f2(*args2, **kwargs2)
     
    args1 = (1,2,3)
    kwargs1 = {'a':4, 'b':5}
     
    args2 = (6,7,8)
    kwargs2 = {'c':9}
     
    f((args1, kwargs1), (args2, kwargs2))
    Ce qui affiche:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    appel de f1
    1
    2
    3
    a => 4 {'a': 4}
    b => 5 {'b': 5}
    appel de f2
    6
    7
    8
    9
    Petite particularité concernant le passage des arguments nommés par dictionnaire:
    - on les passe avec les noms de variables comme des chaines de caractères
    - si dans la fonction appelée ces variables ne sont pas définies (exemple: f1 avec le **kwargs), les clés du dictionnaire restent des chaines
    - si par contre les variables sont définies (ici f2 => c=0), les variables passées (c) sont de vraies variables (on peut faire print c => affiche sa valeur)
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    Juste pour suggérer une amélioration du code de Tyrtamos:
    A la place de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    args1 = (1,2,3)
    kwargs1 = {'a':4, 'b':5}
     
    args2 = (6,7,8)
    kwargs2 = {'c':9}
     
    f((args1, kwargs1), (args2, kwargs2))
    On pourrait écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    _ = lambda *a, **k: (a, k) 
    f(_(1,2,3, a=4, b=5), _(6, 7, 8, c=9))
    Ce qui est plus proche de la syntaxe recherchée.

    - W
    PS: Mais je suis assez perplexe quant à l'intention car transporter des tuple de la forme (list, dict) est une chose. Proposer l'interpréteur Python comme IHM à des utilisateurs sans leur apprendre les rudiments du langage en est une autre.
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. [Flex4] multiples appels d'un même service dans une fonction
    Par polo31 dans le forum Flex
    Réponses: 5
    Dernier message: 01/08/2012, 14h54
  2. Réponses: 6
    Dernier message: 26/04/2010, 13h44
  3. Réponses: 11
    Dernier message: 06/11/2006, 22h51
  4. Select case est-il possible dans ce cas ?
    Par rangernoir dans le forum Access
    Réponses: 10
    Dernier message: 30/09/2005, 16h06
  5. C'est possible dans une requête SELECT ?
    Par Kokito dans le forum Langage SQL
    Réponses: 7
    Dernier message: 15/04/2005, 16h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo