0

I have a simple python script which invokes the main function of another python script. Something like this:

invoker_code.py:

import os
invoked_code = '/tmp/invoked_code.py'
import sys
if os.path.exists(invoked_code):
    sys.append(invoked_code)
else:
    sys.exit(1)
import invoked_code
__data_bag = { 'var' : 'value' }
invoked_code.main()

/tmp/invoked_code.py:

def main():
    print '%s' %(__data_bag['var'])

I want the invoked_code to be able to access the variable __dict_bag from within its code base. This should be achieved with minimal or zero code changes on the invoked_code.py script as this is a third party script and I do not have write access to this script. How can I do that?

5
  • where does invoked_code.py get __data_bag from if is ran directly? Commented Feb 28, 2014 at 0:47
  • Just pass __data_bag to invoked_code.main: invoked_code.main(__data_bag). Commented Feb 28, 2014 at 0:47
  • @zhangxaochen the invoked_code.py would get it from a test data properties file which may not exists at deployment time. Commented Feb 28, 2014 at 0:55
  • @solusipse That's the easiest and I might have to revert back to that. However I was hoping for a bit cleaner solution wherein I wouldn't need to change the invoked_code.py at all Commented Feb 28, 2014 at 0:56
  • 1
    @JourneyMan You have it backwards: The clean solution would be having the function in the invoked code accept the data it wants to work with as a parameter. Commented Feb 28, 2014 at 0:57

2 Answers 2

1

Modules can access and modify each other's global variables:

module1.py:

foobar = [1, 2, 3]
def main():
    print foobar[0]
def printx():
    print x

module2.py:

import module1
print module1.foobar
module1.main()
module1.foobar[0] = 100
module1.main()
module1.x = "exex"
module1.printx()

Running module2.py:

[1, 2, 3]
1
100
exex

Note that you can both modify a global variable in the other module, and also create one. However, I would instead recommend doing as poke said and passing the variable into the invoked function.

Sign up to request clarification or add additional context in comments.

4 Comments

Can you explain as to why the suggested solution by poke is better.
@JourneyMan Claudiu is referring to editing main in invoked_code to accept the data as a parameter.
The thing is the invoked_code is never touched by me. This is a job orchestration framework and I will never have access to the python script that get's executed. Hence I wanted to keep minimal code changes on the invoked_code side.
If that code is a completely separate entity, then it’s even more odd that it is using some module-global variable without offering a way to modify that. And modifying such a variable from the outside is definitely worrying as that could cause side effects you are not aware of—especially when you don’t have control over that code (a variable starting with two underscores usually means private and internal, so you really shouldn’t edit it).
0

The main function in invoked_code will look up the __data_bag name within its own scope. So it will first try to find it inside of the function itself and then go up to module level, i.e. what’s defined in the invoked_code.py.

As __data_bag does not exist in either places, the function won’t be able to find it. So to solve this without changing the invoked_code, you need to supply the data to a place where the function will look at. The only place you have access to is the module though, so that’s the only thing you can do:

import invoked_code
invoked_code.__data_bag = { 'var' : 'value' }
invoked_code.main()

Note that this is really not a good way to solve this problem though. The proper way to solve this would be to have the main function accept a parameter for this:

def main(data_bag):
    print '%s' %(data_bag['var'])

Then you could simply pass the value in your invoking script:

invoked_code.main(__data_bag)

1 Comment

It is possible - see my answer. But yes the correct solution would be to pass it into the function if possible

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.