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 :

Simuler l'éxécution en mode console d'un fichier Python


Sujet :

Python

  1. #1
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut Simuler l'éxécution en mode console d'un fichier Python
    Bonjour,
    voici mon problème du jour. Considérons le code très simple suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #!/usr/bin/env python
    #coding=utf-8
    a = 5
    print a
    a = 2*a
    print a
    Je voudrais faire un petit code Python qui simulerait le mode console, à savoir qui pour le fichier exemple ci-dessus me renverrait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> a = 5
    >>> print a
    5
    >>> a = 2*a
    >>> print a
    10
    Quelque voit-il comment faire sachant que le souci est ici est de récupérer chacune des sorties et les lignes qui les ont produites ?

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    Une proposition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import code
     
    console = code.InteractiveConsole()
     
    def run(str):
        print ">>> " + str
        console.push(str)
     
    with open("exemple.py") as f:
        for l in f:
            run(l.rstrip())

  3. #3
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Génial ! J'ai testé le code suivant et aucun souci...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/usr/bin/env python
    #coding=utf-8
    from sympy import *
    x=Symbol("x")
    limit(sin(x)/x, x, 0)

  4. #4
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    En fait, j'ai un souci. Comment faire pour récupérer dans une chaîne ce qui est écrit dans la console Python ?

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

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    Il faut remplacer sys.stdout par une instance d'une classe avec la méthode write.
    Par exemple :
    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
    import sys
     
    class str_stdout:
        def __init__(self):
            self.stdout = sys.stdout
            self.buffer = ''
            sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
     
    tt = str_stdout()
     
    print "blabla"
     
    tt.close()
     
    # affiche blabla
    print str(tt)

  6. #6
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    J'ai dû zapper quelque chose.

    Quand je lance le code suivant, j'obtiens 1 dans la console Python :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/usr/bin/env python
    #coding=utf-8
    from sympy import *
    x=Symbol("x")
    limit(sin(x)/x, x, 0)
    Quand j'utilise la 1ère méthode, on récupère juste les lignes du fichier à savoir :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> #!/usr/bin/env python
    >>> #coding=utf-8
    >>> from sympy import *
    >>> x=Symbol("x")
    >>> limit(sin(x)/x, x, 0)
    Il faudrait que j'arrive à récupérer cette valeur 1... Autrement dit, il me faut la ligne et ce qui sort éventuellement, et le tout sous forme de chaîne manipulable.

    Si quelqu'un a-t-il une idée ?

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    En mettant les 2 codes ensemble, je n'ai pas de souci (avec Python 2.6.2).
    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
    import code
    import sys
     
    def run(str):
        print ">>> " + str
        console.push(str)
     
    console = code.InteractiveConsole()
     
    class str_stdout:
        def __init__(self):
            self.stdout = sys.stdout
            self.buffer = ''
            sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
     
    tt = str_stdout()
     
    with open("exemple.py") as f:
        for l in f:
            run(l.rstrip())
     
    tt.close()
    print str( tt)
    J'obtiens bien la sortie :
    >>> #!/usr/bin/env python
    >>> #coding=utf-8
    >>> from sympy import *
    >>> x=Symbol("x")
    >>> limit(sin(x)/x, x, 0)
    1

  8. #8
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    J'avais 5 min ce matin. Voilà comment combiner les infos données par manur0 :
    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
    #!/usr/bin/env python
    #coding=utf-8
    import sys
     
    class str_stdout:
        def __init__(self):
            self.stdout = sys.stdout
            self.buffer = ''
            sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
     
    import code
     
    text = []
     
    console = code.InteractiveConsole()
     
    with open("exemple.py") as f:
        for l in f:
            l = l.rstrip()
            tt = str_stdout()
            text.append(">>> " + l)
            console.push(l)
            tt.close()
            tt = str(tt).strip() # Pour éviter de récupérer des lignes vides.
            if tt:
                text.append(tt)
     
    print '\n'.join(text)
    Voici un fichier exemple.py suivi de ce que l'on obtient.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #!/usr/bin/env python
    #coding=utf-8
    from sympy import *
    x=Symbol("x")
    limit(sin(x)/x, x, 0)
    Chaîne renvoyée par le script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> #!/usr/bin/env python
    >>> #coding=utf-8
    >>> from sympy import *
    >>> x=Symbol("x")
    >>> limit(sin(x)/x, x, 0)
    1

    Merci manur0.

  9. #9
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Il reste à gérer les erreurs. Voici un code contenant une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #!/usr/bin/env python
    #coding=utf-8
    a = 5
    print a
    a = 2*a
    c
    print a
    print c
    J'ai essayé ceci mais cela ne marche pas.
    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
    #!/usr/bin/env python
    #coding=utf-8
    import sys
     
    class str_stdout:
        def __init__(self):
            self.stdout = sys.stdout
            self.buffer = ''
            sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
     
    import code
     
    text = []
     
    console = code.InteractiveConsole()
     
    try:
        with open("exemple.py") as f:
            for l in f:
                l = l.rstrip()
                if l:
                    tt = str_stdout()
                    text.append(">>> " + l)
                    console.push(l)
                    tt.close()
                    tt = str(tt).rstrip() # Pour éviter de récupérer des lignes vides.
                    if tt:
                        text.append(tt)
     
    except:
        print 'ERROR'
     
     
    text = '\n'.join(text)
     
    print text.strip()
    L'erreur n'est pas attrapée. Pourquoi ?

    L'idéal serait de récupérer le message d'erreur quelque soit le type d'erreur.

    Toute info. est la bienvenue.

  10. #10
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Je posterais ce week-end une solution consistant à tester tout le script (on m'a donné la réponse sur un autre post, il faut juste que je la retrouve) en renvoyant l'erreur dans une chaîne, et si tout fonctionne alors on crée le mode console.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    9
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 9
    Par défaut
    Ma version finale avec récupération d'erreur :
    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
    import code
    import sys
     
    def run(str):
        print ">>> " + str
        console.push(str)
     
    class catch_stdout_stderr:
        def __init__(self):
            self.stdout = sys.stdout
            self.stderr = sys.stderr
            self.buffer = ''
            sys.stderr = sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
            sys.stderr = self.stderr
     
    console = code.InteractiveConsole()
     
    tt = catch_stdout_stderr()
     
    with open(sys.argv[1]) as f:
        for l in f:
            try:
                run(l.rstrip())
            except:
                console.showtraceback()
     
    tt.close()
    print str( tt)
    J'ai enfin compris où tu voulais en venir : tout ceci permet de donner les chaines à exécuter pour doctest !!!
    Bonne idée

  12. #12
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Citation Envoyé par manur0 Voir le message
    J'ai enfin compris où tu voulais en venir : tout ceci permet de donner les chaines à exécuter pour doctest !!!
    Ce n'est pas que pour cela... Je travaille sur un projet pour taper des maths et des tutos infos pour les formats HTML et PDF via LaTeX.
    Du coup, je voudrais disposer d'un outil simulant le mode console sur des scripts où je n'aurai qu'à donner les lignes de code sans avoir à taper ou copier les lignes de sortie mo même.

    Ceci étant dit, merci pour ton code mais je n'ai pas reéussi à la faire fonctionner avec un chemin de fichier donné. Dès que j'ai 20min de libre, je m'y mets.

  13. #13
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Voilà ce que l'on peut faire. Le code est brouillon mais il y a les grandes lignes et de nouveau merci à manur0.
    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
    #!/usr/bin/env python
    #coding=utf-8
    import sys
    import subprocess
     
    def testfile(filepath):
        x = subprocess.Popen(["python.exe", filepath], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     
        return x.stderr.read()
     
     
    class str_stdout:
        def __init__(self):
            self.stdout = sys.stdout
            self.buffer = ''
            sys.stdout = self
        def write(self, str):
            self.buffer += str
        def __str__(self):
            return self.buffer
        def close(self):
            sys.stdout = self.stdout
     
    import code
     
     
    pathFile = "exemple2.py"
     
    test = testfile(pathFile)
     
    if test:
        print 'Errors found :'
        print test
    else:
        console = code.InteractiveConsole()
        text = []
        with open(pathFile) as f:
            for l in f:
                l = l.rstrip()
                if l:
                    tt = str_stdout()
                    text.append(">>> " + l)
                    console.push(l)
                    tt.close()
                    tt = str(tt).strip() # Pour éviter de récupérer des lignes vides.
                    if tt:
                        text.append(tt)
     
        text = '\n'.join(text)
        print text
    L'inconvénient est que l'on lance deux fois le script mais bon...
    Autre inconvénient que je corrigerais dès que possible et qui lui est gênant : la solution ne fonctionne que sous Windows mais on m'avait donné un snippet pour l'adaptation à Linux. Je ferais cela dans le week-end et je testerais.

  14. #14
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Citation Envoyé par rambc Voir le message
    la solution ne fonctionne que sous Windows mais on m'avait donné un snippet pour l'adaptation à Linux.
    Peut-être en changeant "python.exe" par "python" ?

  15. #15
    Membre éprouvé

    Profil pro
    Account Manager
    Inscrit en
    Décembre 2006
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Account Manager

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 301
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    Peut-être en changeant "python.exe" par "python" ?
    Tout simplement oui. Merci.

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

Discussions similaires

  1. Mises à jour des paquetages en mode console
    Par Memnoch31 dans le forum Debian
    Réponses: 6
    Dernier message: 16/05/2004, 16h30
  2. Des couleurs en mode console
    Par davcha dans le forum MFC
    Réponses: 3
    Dernier message: 08/05/2004, 14h37
  3. Mode console par défaut
    Par sekiryou dans le forum Administration système
    Réponses: 5
    Dernier message: 05/03/2004, 06h38
  4. Mode console et MFC ??
    Par G3G3 dans le forum MFC
    Réponses: 7
    Dernier message: 20/02/2004, 17h49
  5. Editeur en mode console
    Par logramme dans le forum C
    Réponses: 5
    Dernier message: 11/06/2002, 13h23

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