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 :

Appeler un script py depuis un autre script


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut Appeler un script py depuis un autre script
    Bonjour,
    Je continue mes questions naïves, pardonnez moi.

    J'ai donc construit une petite appli en créant plusieurs fichiers py qui correspondent à différentes briques fonctionnelles de l'application.
    Maintenant, je voudrais relier tout ça et en faire un truc cohérent.
    Il faut donc que je relie les briques entre elles et que j'appelle un script depuis un autre script (en fonction du besoin.
    Et c'est là que je coince.

    Je vois plusieurs manières de faire :
    - avoir un fichier de process principal et faire en sorte que tous les autres scripts soient des fonctions, appelées depuis ce fichier principal. Mais cela me semble lourd, m'oblige à réécrire pas mal de code pour adapter, et j'ai cru entrevoir l'idée qu'il me faudrait utiliser des classes, chose que je maîtrise encore moins que le reste. (mais bon... s'il faut apprendre, je m'y collerai )
    -utiliser des choses comme subprocess. J'ai essayé ça, mais je n'y arrive pas. J'ai essayé avec subprocess.run et subprocess.Popen (je n'arrive pas à voir la différence pour l'instant), mais je ne comprends pas, il ne trouve jamais le fichier : J'ai récupéré un exemple sur internet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from subprocess import Popen, PIPE
    process = Popen(['cat', 'test0.py'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    print (stdout)
    J'ai essayé avec le fichier test0.py sur le même path que mon fichier appelant ; j'ai même essayé avec le chemin complet depuis c: mais ça me répond à chaque fois "FileNotFoundError: [WinError 2] Le fichier spécifié est introuvable"
    (j'avoue avoir juste essayé de reproduire le code, pour l'instant, je ne le comprends pas, notamment les différents arguments. Mais tant que je n'arrive pas à le faire marcher, il m'est difficile de tester pour comprendre le truc...)

    Voilà, ce sont les 2 seules idées que j'ai

    Merci d'avance
    Th

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    C'est curieux, très souvent, je rame et je me trouve un peu coincé, alors je me décide à envoyer un message sur le forum ... et puis c'est le moment où je débloque un truc...

    Tout ceci pour dire que j'ai un peu progressé : j'ai lancé le script suivant et il a l'air de s’exécuter sans lancer d'erreur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import subprocess
    subprocess.run("start python3 test0.py", check=True, shell=True)
    ceci dit, il ne se passe rigoureusement rien
    le fichier test est juste censé faire un "print ('hello world')" et je ne vois rien qui s'affiche.

    Th

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 829
    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 829
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Thiplouv Voir le message
    - avoir un fichier de process principal et faire en sorte que tous les autres scripts soient des fonctions, appelées depuis ce fichier principal. Mais cela me semble lourd, m'oblige à réécrire pas mal de code pour adapter, et j'ai cru entrevoir l'idée qu'il me faudrait utiliser des classes, chose que je maîtrise encore moins que le reste. (mais bon... s'il faut apprendre, je m'y collerai )
    Ce serait pourtant le plus adapté. Mais je crois que tu as travaillé à l'envers. Généralement, on fait un truc. Pour ce, on découpe ce truc en petites fonctions qui décomposent le travail. Et si l'ensemble donne un code source trop gros, alors on découpe ce code source en différents modules qu'on peut ensuite importer pour récupérer les fonctions. Et les classes sont un outil très utile mais nullement obligatoire. Effectivement quand on les connait on y vient car on voit la simplicité que ça apporte mais on ne se force pas à y venir en aveugle.

    Citation Envoyé par Thiplouv Voir le message
    -utiliser des choses comme subprocess.
    Ca c'est une autre approche. Cette approche permet de mettre en communication des programmes distincts et fonctionnant déjà par eux-même de façon individuelle. C'est une approche de type Unix car c'est sur cet OS qu'a été inventé le pipe qui permet de faire des grandes choses en utilisant des programmes simples. Effectivement dans les faits ça a le même objectif (au lieu d'utiliser des fonctions individuelles on utilise des programmes individuels pour un but commun) mais y venir sans avoir aucun support quelque part c'est une mauvaise façon de penser. Dans cette approche, on part de programmes déjà existants qui ont été créés parce qu'on en avait besoin. Et de là, c'est après qu'on se dit "ok j'ai ça à obtenir, or il y a déjà un programme qui fait une partie de ça donc peut-être que je peux l'utiliser dans un pipe". On ne se dit pas "ok j'ai ça à obtenir, donc je vais d'abord créer un programme qui fait une partie de ça et ensuite l'utiliser avec un pipe". C'est trop compliqué comme démarche. Autant passer par des fonctions directement utilisables (en plus la techno pipe est une techno bien plus stressante pour l'OS).

    Citation Envoyé par Thiplouv Voir le message
    J'ai essayé ça, mais je n'y arrive pas. J'ai essayé avec subprocess.run et subprocess.Popen (je n'arrive pas à voir la différence pour l'instant), mais je ne comprends pas, il ne trouve jamais le fichier : J'ai récupéré un exemple sur internet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    from subprocess import Popen, PIPE
    process = Popen(['cat', 'test0.py'], stdout=PIPE, stderr=PIPE)
    stdout, stderr = process.communicate()
    print (stdout)
    J'ai essayé avec le fichier test0.py sur le même path que mon fichier appelant ; j'ai même essayé avec le chemin complet depuis c: mais ça me répond à chaque fois "FileNotFoundError: [WinError 2] Le fichier spécifié est introuvable"
    (j'avoue avoir juste essayé de reproduire le code, pour l'instant, je ne le comprends pas, notamment les différents arguments. Mais tant que je n'arrive pas à le faire marcher, il m'est difficile de tester pour comprendre le truc...)
    Ben "cat" est un programme Unix. Le message WinError semble montrer que tu es sous zindow. C'est "cat" qu'il ne trouve pas, pas "test0.py". Essaye de remplacer "cat" par "type" (son équivalent zindow) et ça devrait aller mieux (modulo le fait que la notion de pipe elle-même est une notion Unix et je ne sais pas si zindow a mis en oeuvre cette techno => si ce n'est pas le cas, alors Python ne pourra pas l'utiliser). Et (en remontant le souci d'un cran), si toi-même tu ne sais pas trop comment fonctionnent les pipes, tu auras du mal à les utiliser via Python...
    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]

  4. #4
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    Merci beaucoup pour cette réponse. C'est très clair.
    Oui, je veux bien croire que j'ai travaillé à l'envers, mais c'est le problème du travail de groupe : on découpe le projet en petits morceaux, chacun essaye de fabriquer sa brique qu'il teste de son côté, et ensuite, pour tout réassembler, ça coince plus ou moins...

    Ayant donc des morceaux disjoints (et une équipe qui n'a pas fichu grand chose...), je vais donc essayer avec les subprocess.
    Je viens d'essayer ça, et ça a l'air de marcher...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    process = Popen(['python', 'test0.py'])
    stdout, stderr = process.communicate()
    J'ai viré la référence à PIPE, qui perturbait le résultat, et pour l'instant mes tests fonctionnent. Mais j'aurai peut-être des (mauvaises) surprises plus tard...

    Th

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    Ah j'ai parlé trop vite...
    Mes tests fonctionnaient, comme je l'ai dit, parce qu'ils étaient simplistes : ouverture d'un 2ème process qui disait juste "hell world"...

    Mais en vrai, j'ai besoin de passer une variable du process 1 au process 2. Et ça, je ne sais pas comment faire : même en mettant la variable comme globale, ça ne fonctionne pas (ce que je peux comprendre, le 2ème process étant complètement autonome...

    Du coup, à part sauvegarder la variable en dur dans un fichier txt temporaire (comme une sorte de cookie, en fait), je ne vois pas comment faire

    Th

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    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 718
    Par défaut
    Salut,

    Citation Envoyé par Thiplouv Voir le message
    Du coup, à part sauvegarder la variable en dur dans un fichier txt temporaire (comme une sorte de cookie, en fait), je ne vois pas comment faire
    Apprenez ce que sont modules et packages en ouvrant un tuto... et utilisez ce savoir là pour organiser votre code.

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

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Salut,
    Apprenez ce que sont modules et packages en ouvrant un tuto... et utilisez ce savoir là pour organiser votre code.
    - W
    Bonjour,
    Euh... ce n'est pas très sympa, comme remarque : je suis peut-être débile, mais pas feignant.
    J'ai bien ouvert des tas de tutos, et si j'en suis là, c'est que soit je suis débile, effectivement, soit que ce n'est pas clair, mais en tous cas, je suis déjà passé par cette étape.

    Merci quand même...

    Th

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 829
    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 829
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Thiplouv Voir le message
    Oui, je veux bien croire que j'ai travaillé à l'envers, mais c'est le problème du travail de groupe : on découpe le projet en petits morceaux, chacun essaye de fabriquer sa brique qu'il teste de son côté, et ensuite, pour tout réassembler, ça coince plus ou moins...
    Oui, ce sont les tests unitaires. Mais Python offre aussi un truc pour faciliter ça
    Tu crées un source "toto.py" qui contient diverses fonctions X, Y et Z, fonctions censées faire divers petits travaux distincts pour le projet. Ex
    Code oython : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def X(...):
        ... (travail X)...
    # def X()
     
    def Y(...):
        ... (travail Y)...
    # def Y()
     
    def Z(...):
        ... (travail Z)...
    # def Z()

    Ensuite, tu veux tester ces fonctions, tu rajoutes en dessous ces lignes
    Code oython : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if __name__ == "__main__":
        ... (test de X, Y et Z dans tous les sens)...
    #if

    Ensuite tu peux appeler "python3 toto.py" ce qui appellera la partie "if". En effet, quand un script Python est appelé en tant qu'exécutable, sa variable interne "__name__" contient la chaine "__main__". Et là, tous tes tests programmés s'exécuteront.
    Une fois tes tests validés, et que les fonctions testées dans diverses configurations produisent les bons résultats, tu peux donner le source à l'équipe qui pourra alors l'importer dans le projet (import toto). Dans ce cas, la variable "__name__" ne contient plus "__main__" mais le nom utilisé pour l'import (ici "toto") et donc le if étant devenu faux, le code de test ne s'excute plus mais les fonctions X, Y et Z sont maintenant utilisables dans le projet.

    Citation Envoyé par Thiplouv Voir le message
    (et une équipe qui n'a pas fichu grand chose...)
    Ca c'est un autre souci qui ne provient pas de Python. Là nous on ne peut rien faire

    Citation Envoyé par Thiplouv Voir le message
    Mais en vrai, j'ai besoin de passer une variable du process 1 au process 2. Et ça, je ne sais pas comment faire : même en mettant la variable comme globale, ça ne fonctionne pas (ce que je peux comprendre, le 2ème process étant complètement autonome...
    Très bonne analyse. Effectivement les processus sont indépendants et ont leur propre mémoire perso et isolée. Là tu entres dans les soucis de communication entre processus.

    Citation Envoyé par Thiplouv Voir le message
    Du coup, à part sauvegarder la variable en dur dans un fichier txt temporaire (comme une sorte de cookie, en fait), je ne vois pas comment faire
    Il ya plusieurs technologies indépendantes (je parle pour le monde Unix mais probablement que zindow aura des technos similaires) et chacune aura des avantages et inconvénients
    • utilisation de fichier texte. p1 écrit, p2 peut aller lire. Et inversement. Ne pas oublier ensuite de nettoyer ce qui a été lu ou de trouver une astuce pour ne pas relire 2 fois la même info. Attention aussi aux collisions (comment gérer si par exemple t'es dans une IHM et que 2 zones de saisies font appel à p1) ou la vitesse de réponse de ton disque (style p1 est appelé 5000 fois dans une boucle, comment va réagir le disque à qui tu vas demander d'écrire 5000 fois dans le fichier).
    • utilisation de fichier pipe. C'est exatement la même technologie que les pipes dits "mémoire" sauf que ça passe par un fichier sur disque. p1 écrit, p2 va lire. Là l'effacement n'est pas à gérer car la donnée lue est automatiquement effacée par le noyau Unix.
    • utilisation des IPC (Internal Processus Communication). Ce sont des outils indépendants de tes programmes mais qui sont à ta disposition (par le biais de fonctions d'ouverture et d'accès) dans lesquels tu peux déposer des infos qui seront disponibles pour d'autres processus. La différence avec le pipe c'est que p1 peut déposer des infos puis disparaitre, les infos restent présentes et disponibles pour qui à la clef. Les IPC se divisent en 3 parties: la file de messages (une espèce de fil à linge ou de télésiège sur lequel tu dépose un message qui pourra être récupéré à l'autre bout => les messages sont récupérés dans l'ordre d'écriture), la mémoire partagée (zone mémoire accessible par plusieurs processus) et les sémaphores (une espèce de feu rouge/feu vert qui permet de bloquer ou au contraire laisser passer un processus)
    • utilisation du réseau => ta machine possède un réseau interne accessible par 127.0.0.1, rien n'interdit donc à p1 de demander une connexion à p2. Si p2 lui répond, le réseau est établi et p1 et p2 peuvent se communiquer des infos via TCP/IP
    • utilisation de fichier socket => exactement le même principe que TCP/IP sauf que la communication passe par un fichier disque et non par la pile TCP/IP. Mais mis à part la création du canal de comm (dans un cas c'est une adresse et un port et dans l'autre cas c'est un nom de fichier), les fonctions d'accès aux données sont les mêmes.


    Ou alors, puisque tu sembles parti pour tout faire toi-même, tu fais tout toi-même en passant par des fonctions. Quelque part je pense que même si tu commences par en perdre, à terme tu gagneras du temps...
    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]

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    Merci beaucoup pour ces longues explications.
    Je crois avoir à peu près compris le principe.

    Enfin pour le début, parce que la fin, si j'ai compris l'idée, je ne suis pas sûr de pouvoir appliquer...
    De plus, je pense que ça sort certainement de ce qui m'est demandé...

    Citation Envoyé par Sve@r Voir le message
    Ou alors, puisque tu sembles parti pour tout faire toi-même, tu fais tout toi-même en passant par des fonctions. Quelque part je pense que même si tu commences par en perdre, à terme tu gagneras du temps...
    Oui, c'est très vraisemblable. Je vais plutôt essayer cette piste-là.

    Merci encore !!
    Th

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 718
    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 718
    Par défaut
    Citation Envoyé par Thiplouv Voir le message
    J'ai bien ouvert des tas de tutos, et si j'en suis là, c'est que soit je suis débile, effectivement, soit que ce n'est pas clair, mais en tous cas, je suis déjà passé par cette étape.
    Il est plus simple de faire import d'un module d'y appeler les fonctions que l'on souhaite et récupérer leur retour.

    Si votre code n'est pas été organisé pour fonctionner comme çà, c'est pas l'ajout d'une cloison plus épaisse entre l'appelant de la fonction et la fonction appelée qui simplifiera/résoudra le problème.

    subprocess va se contenter d'exécuter un script.
    Lui passer des paramètres çà va être simple, s'il a prévu de les lire sur sys.args, (s'il y a des "input" çà va être compliqué) quand à en récupérer la sortie, il faudra interpréter des chaines de caractères.

    Pas facile de lui faire exécuter une fonction X ou Y du script en lui passant des paramètres et en récupérant la sortie. Pour çà il faudra modifier le script appelé et accommoder le script appelant.

    De toutes façons, difficile de faire fonctionner quoi que ce soit sans modifier vos scripts! Passer par subprocess au lieu d'utiliser import, çà sera juste plus de boulot.

    Après c'est vous qui allez écrire le code donc, c'est vous qui voyez.

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

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2020
    Messages : 17
    Par défaut
    Bonjour,

    Citation Envoyé par wiztricks Voir le message
    Passer par subprocess au lieu d'utiliser import, çà sera juste plus de boulot.
    - W
    Oui, c'est que j'ai fini par comprendre.
    J'ai donc tout repris pour passer mes scripts secondaires en fonctions et faire des imports, et ça a l'air de fonctionner.

    Merci beaucoup à vous pour votre aide et vos avis !
    Th

Discussions similaires

  1. appel d'une image depuis un autre serveur
    Par isa150183 dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 16/12/2007, 17h08
  2. Réponses: 2
    Dernier message: 04/06/2007, 13h53
  3. Réponses: 4
    Dernier message: 26/04/2007, 09h03
  4. Réponses: 3
    Dernier message: 14/12/2006, 17h31
  5. Appel d'un Formulaire depuis un autre classeur
    Par philmonnery dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 27/07/2006, 11h03

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