2

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?

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this looks promising, trying now.
Thank you very much, it may be a dirty hack but by god it works. Thanks again!
2

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...

5 Comments

Yes I understand why this would normally work, but as I said in my post: "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." Edit: So to clarify, there are scripts in other directories called by ChildOne that depend on the relative path of ChildOne.
I guess I'm still confused -- the example I provided above doesn't require changing any paths, relative or not. Can you provide a full MWE to illustrate the issue?
His problem is that ChildOne has hard-coded relative paths in it that assume that ChildOne is in the current working directory. So when he imports ChildOne from someplace else and tries to use it, things start dying because it can't find files where it expects them.
@ Henry - Precisely, sorry if I was unclear. I'm working with another programmer and I cannot cause his scripts to die by importing ChildOne. I think Henry's answer below might work, trying now.
Henry -- thanks for the clarification. Now the problem makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.