I have written myself a simple function that sieves through my Python folder and look for where a possible module is. What I want to do is simple. I pass a string of module import and the function will find the folder of the module, cd there, and import it to whichever environment I am working in, e.g.:
anyimport('from fun_abc import *')
Originally I tried:
class anyimport(object):
def __init__(self, importmodule, pythonpath='/home/user/Python', finddir=finddir):
##################################################################
### A BUNCH OF CODES SCANNING THE DIRECTORY AND LOCATE THE ONE ###
##################################################################
### "pointdir" is where the directory of the file is ###
### "evalstr" is a string that looks like this : ---
### 'from yourmodule import *'
os.chdir(pointdir)
exec evalstr
As I coded the whole thing in iPython Notebook, it works. So the problem slipped by me. Then I found it does not work properly because the modules the function imports stay in the function's local variable space.
Then I found this Stack Overflow discussion "In Python, why doesn't an import in an exec in a function work?". Thus I changed the code to the following:
class anyimport(object):
def __init__(self, importmodule, pythonpath='/home/user/Python', finddir=finddir):
##################################################################
### A BUNCH OF CODES SCANNING THE DIRECTORY AND LOCATE THE ONE ###
##################################################################
### "pointdir" is where the directory of the file is ###
### "evalstr" is a string that looks like this : ---
### 'from yourmodule import *'
sys.path.append(os.path.join(os.path.dirname(__file__), pointdir))
exec (evalstr, globals())
It still does not work. The function runs without error but the modules are not available to me, say if I run script.py
in which I do anyimport('from fun_abc import *')
but nothing from fun_abc
is there. Python will tell me "NameError: name 'fun_you_want' is not defined".
Would anyone be kind enough to point me in the right direction as to how to solve this problem?
Thank you for your attention and I really appreciate your help!
Attention:
In addition to @Noya's spot-on answer that one has to pass the scope to make the exec
work, to avoid "ImportError", you need to add this line before running exec
:
sys.path.append(os.path.join(os.path.dirname(__file__), pointdir))
exec (evalstr, scope)
This is due to the reason that our modification of sys.path
assumes the current working directory is always in main/
. We need to add the parent directory to sys.path
. See this Stack Overflow discussion "ImportError: No module named - Python" for more information on resolving this issue.