starting a second python script with transfer of variables

dblessin
2014-02-19
2016-01-27
  • dblessin - 2014-02-19

    Hi,
    I tried to start a second python script from the executed script.
    It's possible to use:
    execfile ("C:/path/name.py")
    and the second script is started and executed successfully. But the execfile function can only handle three arguments (filename, a local and a global dictionary) that's not exactly what I need.

    So I tried to use another function from the "exec-family"
    os.execlp("UnterScript.py", "Argument1", "Argument2", "Argument3", "Argument4")
    and got an error message:

    Traceback(most recent call last):
    "C:...*.py", line XY, in <module>
    File "C:...\CODESYS\Scriptlib\3.5.0.0\os.py", line 327, execlp
    File "C:...\CODESYS\Scriptlib\3.5.0.0\os.py", line 344, execlp
    File "C:...\CODESYS\Scriptlib\3.5.0.0\os.py", line 362, execlp
    global name 'execv' is not defined</module>

    The Message differs a little (==> the line numbers) depending if I use execlp or another function of the same family.
    (os, sys and subprocess are imported at the start of the file.)

    Is there a possibility to start and execute a python file from a python file and give a variable like a string or integer within?

     
  • Anonymous - 2014-02-19

    Originally created by: M.Schaber

    Hi,

    Do you want to start the second script within CODESYS, or in a separate process?

    If you want to execute the script within the same process, with access to the CODESYS functionality, then execfile should be the way to go.

    As far as I can see, you can pass the parameters by populating the local and/or global dictionary you pass to execfile(), then they will be just visible as predefined variables within the script.

    Another way might be to manipulate the sys.argv, this way you can simulate the normal command line arguments.

    name=="main" trick.

    On the other hand, using the os.exec-family of functions of the python standard library will start those scripts in a separate process, where they don't have access to the CODESYS functionality (and you need a separate python interpreter installed for it to work). However, it seems that those functions are broken in the IronPython version delivered with your CODESYS. Still, if you want to start the second script in a separate process, you could use the .NET api instead of the Python standard library instead - see the System.Diagnostics.Process API. You could also try os.system().

    HTH,
    Markus

     
  • dblessin - 2014-02-24

    Hi,

    I'd like to start the first script from CODESYS, and the second script from the first script, ideally both able to use CODESYS functionally.

    I was not able to access variables from both scripts, even when they're declared as global (I tried the examples given in: http://openbook.galileocomputing.de/pyt ... 683ab127e3 => I do more work on using dictionary during this week) I was only successful giving variables from the starting script to the second script, not the way back.

    So I decided at the Moment the best way is to make a module (http://tutorial.pocoo.org/modules.html), not exactly what I like, a module can only give back one result (that could be a list, so including more than one variable) but it works.

    best regards,
    daniel

     
  • Anonymous - 2014-02-24

    Originally created by: M.Schaber

    Hi,

    When executing execfile, you can inspect the dictionary/ies you passed as locals and/or globals after the call. execfile is documented to work that way: http://docs.python.org/2/library/functions.html#execfile.

    On the other hand, the cleaner way is to make modules. But why do you think that a module can only "give back one result"?

    When a module is first "executed" during the first import, it populates its namespache with classes and functions.

    The functions can return arbitrary results, including classes or dictionaries. The "normal" python way for simple "multi-component" results are tuples or named tuples, for more complex results, you return an object of a class.

    HTH,
    Markus

     
  • andipandi - 2016-01-27

    I have some similar need.. though it will include some modifications for the script you want to call (2nd script).
    Namely, you would have to call 1 function in that script, and not execute the whole script (it does get executed anyway, but that way you can pass parameters to that function):

    \# get 2nd file as module
    import importlib
    module = importlib.import_module(filename)
    \# you can set codesys globals of module, as you need
    module.projects = projects
    \# get function
    myfunc = getattr(module, functionname)
    \# call with list of arguments in arguments
    myfunc(*arguments)
    

    The import_module will already execute the 2nd script, use some pattern like

    if __name__ == "__main__":
    Β  Β main()
    

    to determine what gets exeucted when starting 2nd script directly or via import. Have your code you want executed when starting directly in main then and no code on a global/script level.

     

Log in to post a comment.