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 :

Référence à une liste en paramètre à un thread


Sujet :

Python

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut Référence à une liste en paramètre à un thread
    Bonjour,

    Je débute en Python, je garde sûrement mes réflexes d'autres langages notamment le C. Et j'ai un soucis pour passer une référence en paramètre à la fonction qui sera exécutée par un thread. Voici des extraits de mon code :

    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
     
    # Variables globales
    BUF_NIVEAU_0 = [0]
     
     
    # Fonction de consommation du buffer
    def consommateur_niveau_i(buffer):
        while len(buffer) != 0:
            print "Consommer une matrice ?"
            raw_input()
            print "On a lu la matrice : {}".format(buffer.pop(0))
     
     
    # Script principal
    consommateur = threading.Thread(None, consommateur_niveau_i, None, {BUF_NIVEAU_0,}, None)
    consommateur.start()
    A l'exécution, j'ai une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Traceback (most recent call last):
      File "/Users/pierregradot/Dropbox/Projets/Python Matrices/generateur_matrices.py", line 140, in <module>
        consommateur = threading.Thread(None, consommateur_niveau_i, None, {BUF_NIVEAU_0,}, None)
    TypeError: unhashable type: 'list'
    Pourtant, si dans le main, je mets uniquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    print "Avant : ", BUF_NIVEAU_0
    consommateur_niveau_i(BUF_NIVEAU_0)
    print "Apres : ", BUF_NIVEAU_0
    , ça marche très bien...

    Comment modifier la création du thread pour que ça marche svp ?

  2. #2
    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,

    Il y a une erreur dans l'appel: les arguments passés (BUF_NIVEAU_0,) doivent être dans un tuple () et non dans un dictionnaire {}.

    Dans un dictionnaire, les clés sont "hashées" pour en accélérer l'accès, mais si on présente une liste comme clé, cela génère une erreur "TypeError: unhashable type: 'list' ".
    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

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Arf ! Une fois qu'on me dit qu'elle est l'erreur, ça me parait tellement évident... Je connais la différence entre tuple, liste et dico, mais je m'emmêle encore les pinceaux avec les symboles pour les représenter..... Merci pour cette réponse !

    Dans la même veine, pourquoi le code suivant ne génère pas d'erreur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def test():
    	print "ceci est la fonction test"
     
    thread_test = threading.Thread(None, test, None, {}, None)
    Est-ce parce que l'interpréteur n'essaye pas de "hasher" le dictionnaire et donc ne se rend pas compte ce n'est pas une liste ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Je ne sais pas quelle version de Python vous utilisez mais { foo, } essaie de construire un "set" en non un "dict".
    La question de "hashable" est liée à l'immutabilité de la chose "utilisée" comme clé du dict ou élément du set.

    Ceci dit, le prototype de thread est Thread(group=None, target=None, name=None, args=(), kwargs={}). La fonction appelée ne prennant qu'un paramètre, inutile d'appeler "Thread" en précisant tous ses défauts: juste ceux qu'on change pour "simplifier" et "préciser":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread(target=consommateur_niveau_i, args=(buffer,))
    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    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
    Citation Envoyé par Bktero Voir le message
    Est-ce parce que l'interpréteur n'essaye pas de "hasher" le dictionnaire et donc ne se rend pas compte ce n'est pas une liste ?
    Comme le dictionnaire est vide, il n'y a pas de problème de hashage de clé! Ce n'est cependant pas normal que ça marche: il faudrait mettre: ({},) pour que l'argument soit bien compris par la fonction.

    C'est en fait la construction du dictionnaire qui génère l'erreur. Un dictionnaire comme {'A':123, 'B':456} peut être passé comme paramètre, mais il faut le placer dans le tuple des arguments:

    A noter que, dans la syntaxe de Python, quand il n'y a qu'un seul élément dans un tuple, il faut le terminer par une virgule.
    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

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Je ne sais pas quelle version de Python vous utilisez mais { foo, } essaie de construire un "set" en non un "dict".
    La question de "hashable" est liée à l'immutabilité de la chose "utilisée" comme clé du dict ou élément du set.
    Ah..... Je ne connaissais pas les sets. Qu'est ce qu'ils ont de différents des listes et des tuples ?
    J'utilise Python 2.7.3, avec IDLE de même version, sous Windows XP ou MacOS X Lion (selon les moments).


    inutile d'appeler "Thread" en précisant tous ses défauts
    C'est intéressant ! J'ai repris la façon d'écrire de la FAQ et venant du C, ce genre de techniques m'est encore pas du tout familier.


    C'est en fait la construction du dictionnaire qui génère l'erreur. Un dictionnaire comme {'A':123, 'B':456} peut être passé comme paramètre, mais il faut le placer dans le tuple des arguments:
    L'argument kwargs de Thread() ne sert-il pas justement à passer un dictionnaire pour lister les paramètres de target ?


    A noter que, dans la syntaxe de Python, quand il n'y a qu'un seul élément dans un tuple, il faut le terminer par une virgule.
    J'avais déjà pris note de ce détail

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut

    L'argument kwargs de Thread() ne sert-il pas justement à passer un dictionnaire pour lister les paramètres de target ?
    Le prototype générique d'un callable est (*args, **kwds).
    ou args est une liste de paramètre positionnels/nommés et **kwds une liste de mots/clés valeurs (**kwds est une représentation d'un dict mais ce n'est pas un dict.

    "def consommateur_niveau_i(buffer):" déclare la fonction avec un seul paramètre positionnel sans valeur par "défaut" => l'appelant est obligé de "renseigner" à l'appel.

    Suivant comment est déclarée le point d'entrée(*), l'interpréteur va "caster" les paramètres d'appels avec ce qu'il trouve dans la déclaration de la fonction.
    (*) un callable est un objet x qui peut être "appelé"/"évalué" i.e. l'interprêteur saura quoi essayer d'appliquer à l'objet associé à "x" lorsqu'il rencontre la construction "x(...)".

    Le passage par "l'interpréteur" lors de l'exécution de l'appel fait toute la flexibilité de Python et si vous venez de la dure école du C vous devrez voue résoudre à prendre le temps de comprendre tout ce que cela "change".

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    vous devrez voue résoudre à prendre le temps de comprendre tout ce que cela "change"
    C'est justement ce que j'essaye de faire ^^
    J'ai déjà utilisé pas mal de langages, de SQL à l'assembleur en passant par C, Kornshell ou VHDL, mais je dois avouer que la souplesse puissante de Python me surprend !

    Votre message est bien au dessus de mon niveau en Python. Je comprends à peu près mais il faut encore que j'étudie le langage pour tout comprendre. Je vais essayer de noter ça dans un coin de ma tête pour la suite de mon apprentissage.

    Merci à vous deux pour vos réponses !

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Au cas où vous ne l'auriez pas remarqué, la documentation Python vient avec un "Python Tutorial" qui décrit et aborde l'ensemble des fonctionnalités du langage.

    Pour les paramètres des fonctions, c'est dans: more-on-defining-functions

    D'autres bouquins sont listés à http://python.developpez.com/livres/

    Bon courage
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Merci pour les liens

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [TSQL] variable à utiliser pour une liste de paramètre
    Par pemathez dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 28/03/2008, 09h34
  2. Réponses: 14
    Dernier message: 27/03/2008, 09h16
  3. [SQL] passage du résultat d'une liste en paramètre d'URL parmi d'autres
    Par sara21 dans le forum PHP & Base de données
    Réponses: 10
    Dernier message: 06/02/2008, 18h01
  4. recupérer une liste de paramètres.
    Par fafarun dans le forum Linux
    Réponses: 2
    Dernier message: 14/10/2007, 12h39
  5. Réponses: 2
    Dernier message: 08/09/2006, 09h00

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