I am trying to import a module given an absolute path. I have read through some posts and I chose to follow one method mentioned in https://stackoverflow.com/a/53311583/19947267 but for some reason it doesnt work; below is my directory. my example directory looks like this:
<root>
|
+- /std1
| |
| +- main.py
|
+- /std2
| |
| +- lib.py
I cd to /std1
and now I want to import a module from lib.py
, but when I implement the following code:
import sys
import os
configfile = '~/std2/'
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
from std2.lib import target_module
It cant seem to recognise std2.lib, the error message was
ModuleNotFoundError: No module named 'std2.lib'
is there something I did wrong here? Can anyone please help?
Messing with sys.path
is almost never the right way to do this. If you must though, then you need to understand that if you append ~/std2/
to the search path, it won't be able to find the name std2
, because the import system searches inside of std2
. And that is what your code does, your approach wasn't working because of this behavior of os.path.dirname
when the string has a leading forward slash:
>>> os.path.dirname(os.path.expanduser('~/std2/'))
'/Users/juan/std2'
>>> os.path.dirname(os.path.expanduser('~/std2'))
'/Users/juan'
So, the simplest fix is:
import sys
import os
configfile = '~/std2' # NOTE NO TRAILING FORWARD SLASH
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
import std2.lib
Or instead, you can change your import statement to use just lib
, so:
import sys
import os
configfile = '~/std2/'
sys.path.append(os.path.dirname(os.path.expanduser(configfile)))
import lib
Better yet, you should use pathlib
instead of os.path
:
import sys
import pathlib
configfile = pathlib.Path("~/std2/")
sys.path.append(str(configfile.expanduser()))
import lib
But if you wanted to be able to import std2
, you could add the parent directory to the path:
import sys
import pathlib
configfile = pathlib.Path("~/std2/")
sys.path.append(str(configfile.expanduser().parent))
import std2.lib
(See how much nicer pathlib
is?)
But I really must reiterate, you almost certainly shouldn't be messing with sys.path
to begin with.