Problème de passage d'un argument de type list à une fonction anonyme en python

TypeError: <lambda>() takes 1 positional argument but 13 were given

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, Dans le cadre de mon projet de semestre, je crée un programme python qui engendre 13 processus fils, puis se scinde ne deux threads: l’un qui attends que tous les processus aient finis et l’autre qui récupère leur sortie pour l’écrire sur un fichier.
Pour des soucis de clarté du code, j’ai voulu mettre la cible du thread créé (ne comportant que peu de lignes) dans une fonction anonyme prenant comme unique argument une liste de tous les processus dont il faut attendre la fin.

join_thread = Thread(
            target=lambda month_proc: (
                [proc.join() for proc in month_proc],
                print('all processes finished'),
                kill(getpid(), SIGUSR1)), 
            args=(month_proc),
            name='join_thread')
    join_thread.start()

Malheureusement, dès que ce thread se lance, je reçoit l’erreur: TypeError: <lambda>() takes 1 positional argument but 13 were given. Les fonctions anonymes ne supportent-elles pas les listes?

Merci de votre réponse!

Édité par charlie02

+0 -0

Cette réponse a aidé l’auteur du sujet

du point de vue de python là, tu donne args=[a,b,c,d,e,f...] alors que toi tu veux que ça soit un tuple dont le premier (et seul) élément est la liste en question. Il faut donc faire args=(month_proc,), la virgule est primordiale.

+1 -0

Cette réponse a aidé l’auteur du sujet

Si tu veux que ta lambda prenne une liste d’arguments plutôt qu’une liste en argument, déclare-la comme telle :

target = lambda *month_proc: (
    ...),

Il n’y a aucune différence avec les fonctions classiques.

Édité par adri1

I don’t mind that you think slowly, but I do mind that you are publishing faster. — W. Pauli

+1 -0
Auteur du sujet

D’accord, merci! Autant j’avais déjà vu passé les tuples avec une virgule à la fin sans en comprendre l’utilité, autant je n’avais jamais vu ce genre de déclaration de variables en python!

+0 -0

Sais-tu pourquoi avec des fonctions "classiques" je n’ai jamais rencontré le problème?

charlie02

Sûrement parce que tu n’avais pas le même cas d’utilisation. Le problème se poserait sinon de la même manière avec n’importe quelle fonction.

Mais d’ailleurs, pourquoi préférer une lambda à une fonction classique ? Surtout avec une lambda multi-lignes qui repose sur l’ordre d’évaluation du tuple pour l’exécution de ses instructions.

Auteur du sujet

Surtout avec une lambda multi-lignes qui repose sur l’ordre d’évaluation du tuple pour l’exécution de ses instructions.

Les tuples ne sont pas exécutés systématiquement de l’élément 0 à l’élément n?

Mais d’ailleurs, pourquoi préférer une lambda à une fonction classique ?

Pour une question de lisibilité du code: je trouvais plus simple de voir les lignes de cette mini-fonction écrites directement ici que d’avoir à les retrouver dans le fichier de code (bien sûr, pour les fois ou les fonctions sont plus costaudes, j’utilise des fonctions classiques.
C’est une mauvaise pratique à ton avis?

+0 -0

Les tuples ne sont pas exécutés systématiquement de l’élément 0 à l’élément n?

Si, mais quand on en est obligé de ruser comme ça pour construire une lambda, c’est que c’est pas une bonne idée. Si ta fonction a plus d’une ligne d’instructions, fais en une fonction classique. Les relecteurs du code te remercieront, ne serait-ce que pour le principe de moindre surprise. Personne ne s’attend à trouver une lambda qui renvoie un tuple pour artificiellement émuler du code multilignes.

I don’t mind that you think slowly, but I do mind that you are publishing faster. — W. Pauli

+2 -0

Pour une question de lisibilité du code: je trouvais plus simple de voir les lignes de cette mini-fonction écrites directement ici que d’avoir à les retrouver dans le fichier de code (bien sûr, pour les fois ou les fonctions sont plus costaudes, j’utilise des fonctions classiques.
C’est une mauvaise pratique à ton avis?

charlie02

Oui, car c’est au contraire assez peu lisible, voire cryptique au niveau du comportement. Oui l’ordre d’évaluation est assuré, mais c’est tellement peu utilisé qu’il est difficile de comprendre ce que tu cherches à faire.

Sache aussi que ta fonction n’a pas besoin d’être définie dans le scope globale du module, elle peut très bien l’être juste avant ton appel à Thread.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte