I have a fairly extensive coding background in multiple environments, but, am new to Python. I thought I had figured out a way to import functions dynamically from an external '.py' file, but am unsure if it is the best way. I found problems with using importlib.import_module()
and importlib.__import__
based on my goal. Is there another way to accomplish what I am doing here? Effectively, I am wanting to have the same result as I would get when using from x import y
where x and y are variables. I thought I would be able to use eval('from '+x+' import '+y)
but this throws a syntax error.
I was hoping to accomplish this by contriving a dictionary with files as the keys (i.e., a file named 'file1.py' would create a key of 'file1') and a list of the desired functions as a list associated with its relative key. This can easily be built either literally, or by reading a path for file names and then using the dir() function to get a list of the functions in each individual file (among many other ways). Next, I hoped to simply use nested for
loops to walk the dictionary keys and their associated key value lists and used eval('from '+key+' import '+currentListItem)
. Unfortunately, this throws a syntax error on the execution of the generated 'from...import...' statement. See below for example code. My problems with importlib (and getattr) is that I am unable to maintain the 'abstraction' provided by this method as I have to define a 'handle' in order to use importlib (i.e., handle = getattr(...)
or handle = importlib.import_module(key)
meaning that I basically have to hard code a 'handle name' for the given module being imported and thus may just as well hard code the 'from file_name import function' statements).
# simplistic example of what I was thinking....
# FILE file.py contains the code...
def asub(p1, p2 = None, p3 = None):
print(p1, p2 if p2 else 'p2 defaulted', p3 if p3 else 'p3 defaulted')
return
# FILE b.py contains the code...
#!/usr/local/bin/python3
subs = {'file':['asub']}
for key in subs:
for subrt in subs[key]:
print("==>", key, subrt)
eval('from '+key+' import '+subrt)
# on execution of b.py (i.e., ```python3 b.py``` I get the following...
Traceback (most recent call last):
File "b.py", line 9, in <module>
eval('from '+key+' import '+subrt)
File "<string>", line 1
from file import asub
^
SyntaxError: invalid syntax
NOTE: I understand that this may not be the greatest thing for importing modules/functions as it tends to 'hide' the information that you would need for documentation and usage of the imported functions.
However, I am sure that there will be instances where this may be useful or where similar methodology may be useful in a case other than importing.
As I said, I am new to Python, so, am looking for feedback/guidance on this in a (cringe) 'Pythonic' sense.
One other thing: I get that eval() can open the door for code insertion but for the above specific use, and given that the files containing the functions are well locked down, I think it should be plenty safe (?)...
Thanks in advance for any feedback