0

In file "A.py" I wrote a function runPyFile which simply is

exec(open(file).read())

But now when I write in file "B.py":

from A import *
runPyFile(myFile)

then the values defined in this myFile file are not available in "B" file. What can I do to be able to use them in "B" file?

3
  • 3
    I'm not entirely sure what your ultimate goal is, but it seems very likely it would be better to do it with Python's normal import mechanism rather than using exec to run other files. Commented May 18, 2022 at 22:32
  • 2
    And if you need to import dynamically, use importlib Commented May 18, 2022 at 22:33
  • More specifically, is there a reason not to simply do from myFile import * instead of runPyFile(myFile)? Importing a module already executes it. Commented May 18, 2022 at 22:59

1 Answer 1

1

exec takes dictionaries to hold the global and local variables in the executed code. Pass in globals() to use the globals of the module it's in.

exec(open(file).read(), globals())

SSince you need to be able to call this from other modules, you can write runPyFile so it accepts a globals dictionary passed by the caller. Then the caller passes its globals().

def runPyFile(file, globals):
    exec(open(file).read(), globals)

runPyFile(myFile, globals())

With a little stack inspection you can get the caller's globals without passing them in explicitly. This is "magic" and relies on details specific to CPython, so use with caution. (The caller can still pass in its own globals if it wants to.)

 from inspect import currentframe

 def runPyFile(file, globals=None):
     if globals is None:
         globals = currentframe().f_back.f_globals
     exec(open(file).read(), globals)

Finally, there's the technique of just using your own dictionary rather than the module's global namespace. This isolates the execed code's variables from any module's and allows you to avoid overwriting values and even classes and functions in your module. You can make a dict subclass that lets you access elements as attributes to make it easier to get to those variables.

 from inspect import currentframe

 class Variables(dict):
     __getattr__ = dict.__getitem__

 def runPyFile(file, globals=None):
     if globals is None:
         globals = Variables()
     exec(open(file).read(), globals)
     return globals

 vars = runPyFile(myFile)
 print(vars.a)    # `a` defined in myFile
 vars.func(...)   # calls `func` defined in myFile
Sign up to request clarification or add additional context in comments.

Comments

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.