I have the following file hierarchy structure:
main.py
Main/A/a.pyb.pyc.pyB/a.pyb.pyc.pyC/a.pyb.pyc.py
From main.py I would like to execute any of the scripts in any of the subfolders.
The user will pass on a string A_a.py or B_a.py. The string will be parsed and changed into A/a.py or B/a.py
I would like the approach to be dynamic, such that adding any subfolder for e.g. D with a.py, b.py and c.py would directly adapt without forcing any import lines to the main.py script.
I know it could be done using shell calls like pOpen. But would like to execute it within the code.
Is it possible?
I added empty __init__.py
files to Main/, A/, B/, and C/
. I also put the following function in each of the .py
files just so we had something to call:
def f():print __name__
In main.py
, the significant function is get_module, which calls import_module from importlib.
import errno
from importlib import import_module
import os
from shutil import copytree
import sysbase = 'Main'def get_module(arg):# 'X_x.py' becomes 'X.x'name = arg.strip('.py').replace('_', '.')# full_name will be 'Main.X.x'full_name = base + '.' + nametry:return import_module(full_name)except ImportError as e:print edef main():# D is not listedprint os.listdir(base)# works for Amod = get_module('A_a.py')if mod:mod.f()# can also call like thismod.__dict__['f']()# doesn't work for Dmod = get_module('D_a.py')if mod:mod.f()mod.__dict__['f']()# copy files from A to Dtry:copytree(os.path.join(base, 'A'),os.path.join(base, 'D'))except OSError as e:print eif e.errno != errno.EEXIST:sys.exit(-1)# D should be listedprint os.listdir(base)# should work for Dmod = get_module('D_a.py')if mod:mod.f()mod.__dict__['f']()if __name__ == '__main__':main()
If all goes well this should be the output:
$ python2.7 main.py
['__init__.py', '__init__.pyc', 'A']
Main.A.a
Main.A.a
No module named D.a
['__init__.py', '__init__.pyc', 'D', 'A']
Main.D.a
Main.D.a