I would like to dynamically import and update modules. The more efficient way would likely be to use importlib
and imp.reload
as suggested by abarnet. However another solution would be to use exec
and compile
. I have a sample script below that demonstrates how a module stored in a string can be called and used on the fly. However, when I call this module in function test
(see below), it does not work, and is giving me an error message global name 'FRUITS' is not defined
. I need some fresh pairs of eyes to point me out why this does not work. Thanks.
module_as_string = """
class FRUITS:
APPLE = "his apple"
PEAR = "her pear"
class foo(object):
def __init__(self):
self.x = 1
def get_fruit(self):
return FRUITS.APPLE
_class_name = foo """
def get_code_object():
return compile(module_as_string, "<string>", "exec")
def test():
exec(get_code_object())
a = eval("_class_name()")
print(a.get_fruit())
if __name__ == "__main__":
# below doesn't work
test()
# below works
exec(get_code_object())
a = eval("_class_name()")
print(a.get_fruit())
-- Edit: Let me know how I can improve this question if you think it is not worthy of asking. Don't just down vote. Thanks.
Within function test
, while FRUIT is a local variable, we do not have direct access to it. To access FRUIT
, an additional container, dict_obj
should be passed in to exec
, which we can then use to access the executed classes from that container. A working example is shown below.
def test():
dict_obj = {}
exec(get_code_object(),dict_obj)
a = dict_obj["_class_name"]()
print(a.get_fruit())