views:

81

answers:

5

Hello,

I've written two python scripts script1.py and script2.py. I want to run script1.py from script2.py and get the content of the variables of script1 created during the execution of script1. Script1 has several functions in which the variables are created including in the main.

rgds,

Bruno

Thank you for all your answers. I've examined your answers and it doesn't seem to work. Here are the guilty scripts I'm talking about :

script1.py

def main(argv):
    """Main of script 1
    Due to the  internal structure of the script this 
    main function must always be called with the flag -d
    and a corresponding argument.
    """
    global now
    now = datetime.datetime.now()

    global vroot_directory
    vroot_directory = commands.getoutput("pwd")

    global testcase_list_file
    testcase_list_file = 'no_argument'

    try:
        opts, args = getopt.getopt(argv, "d:t:", 
            ["directory_path=", "testcase_list="])
    except getopt.GetoptError, err:
        print command_syntax
        sys.exit()
    for opt, arg in opts:
        if opt in ("-d", "--directory"):
            vroot_directory = arg
        if opt in ("-t", "--testcase"):
             testcase_list_file = arg

    def function1():
        pass  

    def function2():
        if testcase_list_file == 'no_argument':
            function1()
        else:
            function2()

if __name__ == "__main__":
    main(sys.argv[1:]) 

script2.py

from Tkinter import *

class Application:
    def __init__(self):
        """ main window constructor """
        self.root = Tk()
        # I'd like to import here the variables of script1.py
        self.root.title(script1.vroot_directory)   ?
        self.root.mainloop()

# Main program
f = Application()

Sorry for my mistakes and thank you for your pertinent remarks. I've got the following error message :

" AttributeError: 'module' object has no attribute 'vroot_directory' "

To be more specific I'd like to have something similar to the following :

from Tkinter import *
import script1

class Application:
    def __init__(self):
        """ main window constructor """
        self.root = Tk()
        script1.main(-d directory -t testcase_list_file) # to launch script1
        self.root.title(script1.vroot_directory)   # and after use its variables and functions
        self.root.mainloop()

# Main program
f = Application()

rgds,

A: 

Depending on how many variables you want to pass to script2.py you could pass them via arguments and pick them up as an argv array. You could run script1.py then from this script run os.system('script2.py arg0 arg1 arg2 arg3') to call script2.py.

Then you can pick up your variables in you script2.py by doing this:

import sys

arg0 = sys.argv[0]
arg1 = sys.argv[1]
...
Martin
-1 You shouldn't communicate between Python modules with the command line.
katrielalex
Sure, it is just a suggestion, perhaps this turns out to be the only way in his circumstance that he can achieve his goal.
Martin
Well, OK, but I can't think of any circumstances where you'd have to do this. `pickle` would be a better way of passing data if you couldn't do it at runtime.
katrielalex
+4  A: 

From script2 do

import script1

This will run any code inside script1; any global variables will be available as e.g. script1.result_of_calculation. You can set global variables as below.


script1:

from time import sleep
def main( ):
    global result
    sleep( 1 ) # Big calculation here
    result = 3

script2:

import script1
script1.main( ) # ...
script1.result # 3

Note that it would be nicer to make main() in script1 return result, so that you could do

import script1
result = script1.main( )

This better encapsulates the flow of data, and is generally more Pythonic. It also avoids global variables, which are generally a Bad Thing.

katrielalex
A: 

There are two possibilities: First, merge them into a single script. This could look something like (in script2.py)

import script1

...
script1.dostuff()
importantvar = script1.importantvar
doScript2Stuff(importantvar)

Without knowing your application, however, I'd advise encapsulating whatever script1 does into a function such that you can simply call

(var1, var2, var3) = script1.dostuffAndReturnVariables()

since it's always good to avoid global variables. Also, it may turn out handy later on if the stuff in script1 isn't executed in the moment you import it (as it is done if you write all the commands directly on the main level), but when you want it, by calling a function. Otherwise things may get messy once you get more modules and you may find yourself rearranging import commands because they do so much stuff.

Second possibility, if, for some reason, they need to be run separately, would be to use pickle.

Write

output = open(picklefile, "w")
pickle.dump(vars, output)    
output.close()

in script1.py

and then

inputfile = open(picklefile, "r")
vars = pickle.load(inputfile)
input.close()

in script2.py. This way, you save the contents of your var in a file and can revive them from there when needed.

However, I'd prefer the first approach unless there's a really good reason for the two not to be run together, as it improves the structure of your code.

Nicolas78
A: 

Python is an interpreted language, so when you simply import a script within another script (e.g. by writing import script1 inside script2) then the interpreter will load the second script and execute it step by step. Each function definition will result in a callable function object and so on, and each expression will be simply executed.

After that, you can access everything from the module with script1.globalvar1 and so on.

tux21b
is this behaviour really related to python being an interpreted language? (not a rhetorical question ;)
Nicolas78
This concept is at least not working with a linked language, because then only some references are set during the linking process, but no statements are executed. In such a language, you would have to put everything inside a initialize function and call it manually.
tux21b
A: 

I think what you are looking for is some form of object persistence. I personally use the shelve module for this:

Script 1:

import shelve

def main(argv):
    """Main of script 1
    Due to the  internal structure of the script this 
    main function must always be called with the flag -d
    and a corresponding argument.
    """

    settings = shelve.open('mySettings')

    global now
    now = datetime.datetime.now()

    settings['vroot_directory'] = commands.getoutput("pwd")

    settings['testcase_list_file'] = 'no_argument'

    try:
        opts, args = getopt.getopt(argv, "d:t:", 
            ["directory_path=", "testcase_list="])
    except getopt.GetoptError, err:
        print command_syntax
        sys.exit()
    for opt, arg in opts:
        if opt in ("-d", "--directory"):
            settings['vroot_directory'] = arg
        if opt in ("-t", "--testcase"):
            settings['testcase_list_file'] = arg

    def function1():
        pass  

    def function2():
        if testcase_list_file == 'no_argument':
            function1()
        else:
            function2()

if __name__ == "__main__":
    main(sys.argv[1:]) 

Script 2:

from Tkinter import *
import shelve

class Application:
    def __init__(self):
        settings = shelve.open('mySettings')

        """ main window constructor """
        self.root = Tk()
        # I'd like to import here the variables of script1.py
        self.root.title(settings['vroot_directory'])   ?
        self.root.mainloop()

# Main program
f = Application()

The shelve module uses the pickle module in its implementation, so you could also look at pickle module for another approach.

g.d.d.c
Thanks ! I'm going to try this approach.
Bruno
I've tried it but unfortunately it doesn't work, the following message appears :keyError: 'vroot_directory' (I've got the same message if I try to get another variable like now)
Bruno
@Bruno - If you're getting a key error there are a couple possible explanations. Are both programs run from the same directory? If you check where you invoked the files from and their container directories do you find a mySettings file? You may need to provide a full path to shelve.open() in both scripts to ensure they pick up the same object.
g.d.d.c
Thanks for the tips.I've looked at the mySettings file and it is in the right directory. I've changed the paths to absolute paths and the result is the same. To launch the program I've tried in script2.py an os.system(" ./script.py -d directory -t testcase_list_file") (after doing a chmod +x on script1.py) and I got the message sh: script1.py: command not found on the terminal.rgds,
Bruno
My mistake : after another try everything works great ! Thanks a lot gddc and everyone for your time and help.rgds,
Bruno