Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to import from absolute path in python 3.8?

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

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

ModuleNotFoundError: No module named 'std2.lib'

is there something I did wrong here? Can anyone please help?

>Solution :

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 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().name))
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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading