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 :

Threading récupérer la valeur de sortie de inqueue.put


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut Threading récupérer la valeur de sortie de inqueue.put
    Bonjour à tous,

    J'essaie de créer un système interactif ou dit autrement d'émuler une console Python.
    Je me suis inspiré de la console de l'extension LibreOffice APSO. Je pourrai donner plus de précision si nécessaire.

    Comme l'illustre l'image, le code fonctionne.
    Je calcule 2+3, j'affecte à a la valeur 10, elle est conservée, puis je calcule 2*a.
    Cependant la fonction com retourne 'None' alors que je voudrais qu'elle renvoie les résultats affichés 5 dans le premier cas ou 20 dans le second.
    Nom : Capture.png
Affichages : 311
Taille : 19,9 Ko
    Que dois-je changer pour obtenir le résultat attendu c'est à dire que la fonction com renvoie '5' ou '20' ?
    Le module utilisé : essai.py

    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    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 741
    Par défaut
    Citation Envoyé par ddorange Voir le message
    Que dois-je changer pour obtenir le résultat attendu c'est à dire que la fonction com renvoie '5' ou '20' ?
    5 ou 20, c'est éventuellement ce qui sera affiché sur stdout par l'InteractiveConsole... que vous n'essayez même pas de lire.

    Reste l'intention de base: "J'essaie de créer un système interactif ou dit autrement d'émuler une console Python"... et le travail de conception à faire pour détailler ce que ça veut dire et le code à mettre en face.

    Car pour l'instant vous testez (mal) une piste sans trop savoir où ça va vous mener...

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

  3. #3
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Bonsoir,
    Certes je teste une piste mais je sais très bien ce que je veux : que la fonction com retourne le résultat du calcul '2+3' pour le premier ou 2*a soit 20 pour le second.
    Et si je n'utilise pas stdout de l'InteractiveConsole c'est que je ne sais pas faire.
    Plus généralement, quand on pose une question c'est qu'on a pas la réponse ?

    Didier DP.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 540
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 540
    Par défaut
    queue.put ne renvoie rien, donc le a vaudra None quoique tu fasses avec.
    perso, si je lance ton script, je ne peux rien faire
    Si je rajoute com('5') à la fin, je ne vois que le résultat 5, si je fais un print(com('5')), j'ai le 5 et None

  5. #5
    Membre averti
    Homme Profil pro
    Dmaths
    Inscrit en
    Février 2006
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Dmaths
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2006
    Messages : 19
    Par défaut
    Citation Envoyé par umfred Voir le message
    queue.put ne renvoie rien, donc le a vaudra None quoique tu fasses avec.
    Le inqueue.put ne renvoie rien, mais il affiche le résultat dans la console. Il devrait bien y avoir un moyen d'intercepter ce résultat.

    Ce qui suit suppose que Libreoffice soit installé. L'extension Apso émule une console Python.
    Pour vérifier lancer Outils -> Macros -> Gérer les Scripts Python, puis Mes macros -> APSO -> Tools -> Console -> Lancer.
    On tape 2+3 le retour est 5
    Le fichier apso_utils.py contient le code : Roaming -> LibreOffice -> 4 -> user -> uno_packages -> cache -> uno_packages -> ... -> apso.oxt -> python -> pythonpath
    A la ligne 590 de la classe ConsoleWindow on trouve self.inqueue.put(line) qui permet de faire afficher le résultat de 2+3 soit 5 dans la boîte de dialogue.

    C'est donc faisable d'utiliser inqueue.put pour obtenir un résultat.

    apso.oxt.zip

    Voili, voilà ...

    Merci pour votre aide.

  6. #6
    Expert confirmé
    Avatar de jurassic pork
    Homme Profil pro
    Bidouilleur
    Inscrit en
    Décembre 2008
    Messages
    4 212
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Bidouilleur
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2008
    Messages : 4 212
    Par défaut
    Hello,
    j'ai fait une tentative en utilisant une Queue de sortie pour récupérer la valeur à l'intérieur du thread en capturant dans celui-ci le stdout . Voici le 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
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    import threading
    import code
    import sys
    import traceback
    import contextlib
    from io import StringIO
    import copy
     
     
    EOT = b'\x04'
    #from sympy import sympify
    try:
        import queue
        #import builtins
    except ImportError:
        import Queue as queue
        #import __builtin__ as builtins
     
    @contextlib.contextmanager
    def capture():
        oldout,olderr = sys.stdout, sys.stderr
        try:
            out=[StringIO(), StringIO()]
            sys.stdout,sys.stderr = out
            yield out
        finally:
            sys.stdout,sys.stderr = oldout, olderr
            out[0] = out[0].getvalue()
            out[1] = out[1].getvalue()
     
     
    class InteractiveConsole(code.InteractiveConsole):
        def __init__(self, inqueue, exitevent,outqueue):
            code.InteractiveConsole.__init__(self)
            self.inqueue = inqueue
            self.outqueue = outqueue
            #self.exitevent = exitevent
            self.keep_prompting = True
            self.stdin = sys.stdin
            sys.stdin = self
     
     
        def readline(self):
            '''Implement sys.stdin readline method'''
            rl = self.inqueue.get()
            if rl == KeyboardInterrupt:
                print("KbInterrupt")
                raise KeyboardInterrupt()
            if rl == EOT:
                print("EOT")
                self.keep_prompting = False
            return rl
     
     
        def interact(self):
            more = 0
            try:
                while self.keep_prompting:
                    try:
                        #self.outqueue.queue.clear()
                        line = self.raw_input('')
                        with capture() as out:
                            more = self.push(line)
                        self.inqueue.task_done()
                        self.outqueue.put(out[0])
                    except KeyboardInterrupt:
                        self.write("\nKeyboardInterrupt\n")
                        self.resetbuffer()
                        more = 0
                    except SystemExit:
                        self.exitevent.set()
                    except:
                        print('INTERACT\n')
                        traceback.print_exc()
                        self.resetbuffer()
                        more = 0
            finally:
                sys.stdin = self.stdin
                #sys.stdout = self.stdout
     
     
     
     
    def run_interact(*args):
        '''Start the"python interpreter" engine'''
        iconsole = InteractiveConsole(*args)
        iconsole.interact()
     
     
    #EOT = b'\x04'
     
     
    inqueue = queue.Queue()
    outqueue = queue.Queue()
    exitevent = threading.Event()
    result=""
    proc = threading.Thread(target=run_interact, args=(inqueue, exitevent,outqueue))
    proc.start()
     
     
    #prompt = '...'
    def com(x):
        try:
            inqueue.put(x)
            #inqueue.join()
        except:
            inqueue.put(traceback.format_exc())    
        return "com : " + outqueue.get(True,3)
     
     
     
    def ecrit(x):
        return format(x)
    voici ce que j'obtiens dans Thonny (dans Pycharm cela ne marche pas certainement à cause de la gestion des stdin stdout) :

    Nom : ThonnyConsole.png
Affichages : 271
Taille : 3,4 Ko
    déjà une question : n'y-a-t-il pas plus simple pour récupérer le résultat ?
    Cela ne fonctionne pas dans LibreOffice en appelant la macro comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub testConsole()
    Dim masterSPF As Object, scriptP As Object, monScript As Object
    Dim data
    data = Array("2+2")
    masterSPF = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory")
    scriptP = masterSPF.createScriptProvider("")
    monScript = scriptP.getScript("vnd.sun.star.script:ModulesPython|ModConsole.py$com?language=Python&location=user")
    resultat = monScript.invoke(data, Array(), Array())
    Print resultat
    ce qui se passe : il y a un timeout sur le outqueue.get(True,3) me disant que la Queue est vide. peut-être un mauvais passage de paramètre dans les args de threading.Thread ?

    Pour ceux qui vont dire pour la fonction com il suffit de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     def com(x):
           return eval(x)
    mais cela doit fonctionner avec aussi des affectations, des instructions et des enchaînements de commandes.

    [EDIT] j'ai trouvé un article concernant l'utilisation des queues avec les threads ici : Thread Pipeline in Python

    Ami calmant, J.P

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par ddorange Voir le message
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    res = outqueue.get(True,3)
    pos = res.find('\n')
        if pos>=0:
            return res[0:pos]
        else:
            return res
    return outqueue.get(True,3).replace("\n", "") ou mieux, return outqueue.get(True,3).strip().
    Accessoirement c'est plus propre de spécifier explicitement l'exception attendue plutôt que de ratisser large du style "bof je vais pas me fouler sur rechercher la cause du souci"...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/10/2017, 13h16
  2. Réponses: 4
    Dernier message: 19/08/2014, 10h25
  3. [thread] Récupérer la valeur d'un JTextField
    Par _xme_ dans le forum Débuter
    Réponses: 0
    Dernier message: 27/09/2010, 10h08
  4. [VB.net][OleDB]récupérer la valeur d'un parametre de sortie
    Par glanumf dans le forum Accès aux données
    Réponses: 4
    Dernier message: 17/10/2006, 17h09
  5. récupérer la valeur de sortie d'un thread
    Par jakouz dans le forum Langage
    Réponses: 3
    Dernier message: 31/07/2002, 11h28

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