2 votes

Python - Exécution d'une fonction dans un autre script dans un dossier enfant

J'ai un script principal qui exécute plusieurs scripts enfants dans les sous-dossiers du répertoire principal.

La hiérarchie des dossiers ressemble à ceci :

MyFolder\MasterScript.py
MyFolder\ChildOneScript\ChildOne.py
MyFolder\ChildTwoScript\ChildTwo.py
MyFolder\ChildThreeScript\ChildThree.py

Dans MasterScript, j'ai besoin d'appeler une fonction dans ChildOne "myChildFunction" et de lui passer quelques variables. Le problème est que je ne peux pas simplement faire

import ChildOneScript.ChildOne as ChildOne
ChildOne.myChildFunction

parce qu'il y a d'autres scripts qui dépendent du chemin relatif de ChildOne. Donc, si j'importe ChildOne dans le répertoire MyFolder depuis MasterScript et que j'appelle myChildFunction là-bas, j'obtiens des erreurs de traçage indiquant que d'autres fichiers ne peuvent pas être trouvés. Cela est dû aux erreurs d'un autre programmeur têtu qui refuse de modifier ses appels de chemin relatif, car c'est beaucoup de travail manuel.

Alors, est-il possible d'appeler myChildFunction depuis MasterScript et de lui passer des variables ?

Je sais que je peux utiliser subprocess.call et son argument cwd pour changer le répertoire de travail, mais je n'arrive pas à savoir s'il est possible d'appeler la fonction spécifique myChildFunction et de lui passer des variables en utilisant subprocess.

Modifier: Est-il possible de passer des variables en utilisant execfile ?

2voto

Henry Keiter Points 8851

Vous pouvez toujours le pirater avec le module os. Ce n'est pas joli, mais c'est probablement la meilleure solution sans avoir à réécrire tout le code de l'autre personne. Si vous allez utiliser souvent des fonctions des autres scripts, je créerais un intermédiaire pour les rendre plus faciles à appeler :

import sys
import os

def call_legacy_func(func, *args, **opts):
    prev = os.path.abspath(os.getcwd()) # Sauvegarde du répertoire de travail actuel
    try:
        # Obtenir l'emplacement physique de l'enfant.
        func_path = sys.modules[func.__module__].__file__
    except:
        # Arrêt; on nous a passé une fonction intégrée (pas de __file__)
        # Ou vous pourriez juste l'appeler, je suppose: return func(*args, **opts)
        return None

    # Changer pour le répertoire attendu et exécuter la fonction.
    os.chdir(func_path)
    result = func(*args, **opts)

    # Rétablir le répertoire de travail, et retourner.
    os.chdir(prev)
    return result

import ChildOneScript.ChildOne as ChildOne
call_legacy_func(ChildOne.myChildFunction, 0, 1, kwarg=False)

2voto

Paul M. Points 568

Pouvez-vous s'il vous plaît clarifier votre problème? En particulier, il n'est pas clair pour moi quel est votre problème avec la disposition du dossier et l'importation à partir des sous-scripts.

Par exemple, si je crée la structure de répertoire suivante:

/exemple
    __init__.py
    master.py
    /enfantun
        __init__.py
        enfantun.py
    /enfantdeux
        __init__.py
        enfantdeux.py

Où les __init__.py sont simplement des fichiers vides et les fichiers sources sont les suivants:

# master.py
from enfantun.enfantun import enfantun_fxn
from enfantdeux.enfantdeux import enfantdeux_fxn

print "Appel de l'enfant un"
enfantun_fxn()

print "Appel de l'enfant deux"
enfantdeux_fxn()

--

# enfantun.py
def enfantun_fxn():
    print "bonjour de l'enfant un"

--

def enfantdeux_fxn():
    print "bonjour de l'enfant deux"

Depuis le répertoire /exemple, je peux alors exécuter master.py et obtenir la sortie attendue:

exemple $ python master.py 
Appel de l'enfant un
bonjour de l'enfant un
Appel de l'enfant deux
bonjour de l'enfant deux       

Vous pouvez bien sûr utiliser le module subprocess si vous voulez traiter les scripts enfants comme n'importe quel autre exécutable, mais je ne vois aucune raison pour laquelle vous ne devriez pas pouvoir importer directement les scripts enfants. Mais peut-être que je ne comprends pas votre question...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X