Question

I have a master script that executes several child scripts within subfolders of the main directory.

The folder hierarchy looks like:

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

From MasterScript, I need call a function in ChildOne "myChildFunction" & pass some variables to it. The problem is, I cannot simply do

import ChildOneScript.ChildOne as ChildOne
ChildOne.myChildFunction

because there are other scripts that depend on the relative path of ChildOne. So if I import ChildOne to the MyFolder directory from the MasterScript and call myChildFunction there, I get traceback errors saying other files cannot be found. This is due to the mistakes of another stubborn programmer that refuses change his relative path calls, as it is a lot of manual work.

So, is there a way to call myChildFunction from within MasterScript and pass it some variables?

I'm aware I can use subprocess.call and it's cwd argument to change the working directory, but I can't figure out if it's possible to call the specific myChildFunction and pass it varaibles using subprocess.

Edit: Is it possible to pass variables using execfile?

Was it helpful?

Solution

You can always hack it with the os module. It's not pretty, but it's probably the best you can do without rewriting all the other guy's code. If you'll be using functions from the other scripts a lot, I'd write a wrapper for the them to make it easier to call them:

import sys
import os

def call_legacy_func(func, *args, **opts):
    prev = os.path.abspath(os.getcwd()) # Save the real cwd
    try:
        # Get the child's physical location.
        func_path = sys.modules[func.__module__].__file__
    except:
        # Die; we got passed a built-in function (no __file__)
        # Or you could just call it, I guess: return func(*args, **opts)
        return None

    # Change to the expected directory and run the function.
    os.chdir(func_path)
    result = func(*args, **opts)

    # Fix the cwd, and return.
    os.chdir(prev)
    return result

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

OTHER TIPS

Can you please clarify your problem? In particular, it's unclear to me what your issue with the folder layout and importing from subscripts is.

For example, if I create the following directory structure:

/example
    __init__.py
    master.py
    /childone
        __init__.py
        childone.py
    /childtwo
        __init__.py
        childtwo.py

Where the __init__.py are simply empty files and the source files are as follows:

# master.py
from childone.childone import childone_fxn
from childtwo.childtwo import childtwo_fxn

print "Calling child one"
childone_fxn()

print "Calling child two"
childtwo_fxn()

--

# childone.py
def childone_fxn():
    print "hello from child one"

--

def childtwo_fxn():
    print "hello from child two"

From within /example I can then run master.py and get the expected output:

example $ python master.py 
Calling child one
hello from child one
Calling child two
hello from child two       

You can of course use the subprocess module if you want to treat the child scripts like any other executable, but I can't see any reason why you shouldn't be able to import the child scripts directly. But perhaps I'm misunderstanding your question...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top