How do I import a Python module given its relative path?
For example, if
Bar.py, how do I import
Here’s a visual representation:
dirFoo Foo.py dirBar Bar.py
Foo wishes to include
Bar, but restructuring the folder hierarchy is not an option.
Be sure that dirBar has the
__init__.py file — this makes a directory into a Python package.
If you structure your project this way:
src __init__.py main.py dirFoo __init__.py Foo.py dirBar __init__.py Bar.py
Then from Foo.py you should be able to do:
from dirFoo.Foo import FooObject
Per Tom’s comment, this does require that the
src folder is accessible either via
site_packages or your search path. Also, as he mentions,
__init__.py is implicitly imported when you first import a module in that package/directory. Typically
__init__.py is simply an empty file.
You could also add the subdirectory to your Python path so that it imports as a normal script.
import sys sys.path.insert(0, <path to dirFoo>) import Bar
This is the relevant PEP:
In particular, presuming dirFoo is a directory up from dirBar…
from ..dirBar import Bar
The easiest method is to use sys.path.append().
However, you may be also interested in the imp module.
It provides access to internal import functions.
# mod_name is the filename without the .py/.pyc extention py_mod = imp.load_source(mod_name,filename_path) # Loads .py file py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file
This can be used to load modules dynamically when you don’t know a module’s name.
I’ve used this in the past to create a plugin type interface to an application, where the user would write a script with application specific functions, and just drop thier script in a specific directory.
Also, these functions may be useful:
imp.find_module(name[, path]) imp.load_module(name, file, pathname, description)
Add an __init__.py file:
dirFoo Foo.py dirBar __init__.py Bar.py
Then add this code to the start of Foo.py:
import sys sys.path.append('dirBar') import Bar
In my opinion the best choice is to put __ init __.py in the folder and call the file with
from dirBar.Bar import *
It is not recommended to use sys.path.append() because something might gone wrong if you use the same file name as the existing python package. I haven’t test that but that will be ambiguous.
import os import sys lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib')) sys.path.append(lib_path) import mymodule
Just do simple things to import the .py file from a different folder.
Let’s say you have a directory like:
Then just keep an empty file in lib folder as named
And then use
from lib.abc import <Your Module name>
__init__.py file in every folder of the hierarchy of the import module.
Assuming that both your directories are real Python packages (do have the
__init__.py file inside them), here is a safe solution for inclusion of modules relatively to the location of the script.
I assume that you want to do this, because you need to include a set of modules with your script. I use this in production in several products and works in many special scenarios like: scripts called from another directory or executed with python execute instead of opening a new interpreter.
import os, sys, inspect # realpath() will make your script run, even if you symlink it :) cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() )))) if cmd_folder not in sys.path: sys.path.insert(0, cmd_folder) # Use this if you want to include modules from a subfolder cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() )),"subfolder"))) if cmd_subfolder not in sys.path: sys.path.insert(0, cmd_subfolder) # Info: # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!! # __file__ fails if the script is called in different ways on Windows. # __file__ fails if someone does os.chdir() before. # sys.argv also fails, because it doesn't not always contains the path.
As a bonus, this approach does let you force Python to use your module instead of the ones installed on the system.
Warning! I don’t really know what is happening when current module is inside an
egg file. It probably fails too.
from .dirBar import Bar
from dirBar import Bar
just in case there could be another dirBar installed and confuse a foo.py reader.
Call me overly cautious, but I like to make mine more portable because it’s unsafe to assume that files will always be in the same place on every computer. Personally I have the code look up the file path first. I use Linux so mine would look like this:
import os, sys from subprocess import Popen, PIPE try: path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines() if not sys.path.__contains__(path): sys.path.append(path) except IndexError: raise RuntimeError("You must have FILE to run this program!")
That is of course unless you plan to package these together. But if that’s the case you don’t really need two separate files anyway.
Here’s a way to import a file from one level above, using the relative path.
Basically, just move the working directory up a level (or any relative location), add that to your path, then move the working directory back where it started.
#to import from one level above: cwd = os.getcwd() os.chdir("..") below_path = os.getcwd() sys.path.append(below_path) os.chdir(cwd)
If you are just tinkering around and don’t care about deployment issues, you can use a symbolic link (assuming your filesystem supports it) to make the module or package directly visible in the folder of the requesting module.
ln -s (path)/module_name.py
ln -s (path)/package_name
Note: A “module” is any file with a .py extension and a “package” is any folder that contains the file
__init__.py (which can be an empty file). From a usage standpoint, modules and packages are identical — both expose their contained “definitions and statements” as requested via the
The easiest way without any modification to your script is to set PYTHONPATH environment variable. Because sys.path is initialized from these locations:
You sys.path will contains above path, as show below:
print sys.path ['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
Relative sys.path example:
# /lib/my_module.py # /src/test.py if __name__ == '__main__' and __package__ is None: sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib'))) import my_module
Based on this answer.
For this case to import Bar.py into Foo.py, first I’d turn these folders into Python packages like so:
dirFoo __init__.py Foo.py dirBar __init__.py Bar.py
Then I would do it like this in Foo.py:
from .dirBar import Bar
If I wanted the namespacing to look like Bar.whatever, or
from . import dirBar
If I wanted the namespacing dirBar.Bar.whatever. This second case is useful if you have more modules under the dirBar package.
Well, as you mention, usually you want to have access to a folder with your modules relative to where your main script is run, so you just import them.
I have the script in
D:/Books/MyBooks.py and some modules (like oldies.py). I need to import from subdirectory
import sys,site site.addsitedir(sys.path + '\includes') print (sys.path) # Just verify it is there import oldies
oldies.py, so you verify everything is going OK. This way always works because by the Python definition
sys.path as initialized upon program startup, the first item of this list,
path, is the directory containing the script that was used to invoke the Python interpreter.
If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input),
path is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of
Another solution would be to install the py-require package and then use the following in
import require Bar = require('./dirBar/Bar')
I’m not experienced about python, so if there is any wrong in my words, just tell me. If your file hierarchy arranged like this:
project module_1.py module_2.py
module_1.py defines a function called
from module_1 import func_1 def func_2(): func_1() if __name__ == '__main__': func_2()
and you run
python module_2.py in cmd, it will do run what
func_1() defines. That’s usually how we import same hierarchy files. But when you write
from .module_1 import func_1 in
module_2.py, python interpreter will say
No module named '__main__.module_1'; '__main__' is not a package. So to fix this, we just keep the change we just make, and move both of the module to a package, and make a third module as a caller to run
project package_1 module_1.py module_2.py main.py
from package_1.module_2 import func_2 def func_3(): func_2() if __name__ == '__main__': func_3()
But the reason we add a
module_2.py is that if we don’t do that and run
main.py, python interpreter will say
No module named 'module_1', that’s a little tricky,
module_1.py is right beside
module_2.py. Now I let
module_1.py do something:
def func_1(): print(__name__)
__name__ records who calls func_1. Now we keep the
module_1 , run
main.py, it will print
module_1. It indicates that the one who calls
func_1() is at the same hierarchy as
. imply that
module_1 is at the same hierarchy as
module_2.py itself. So if there isn’t a dot,
main.py will recognize
module_1 at the same hierarchy as itself, it can recognize
package_1, but not what “under” it.
Now let’s make it a bit complicated. You have a
config.ini and a module defines a function to read it at the same hierarchy as ‘main.py’.
project package_1 module_1.py module_2.py config.py config.ini main.py
And for some unavoidable reason, you have to call it with
module_2.py, so it has to import from upper hierarchy.module_2.py:
import ..config pass
Two dots means import from upper hierarchy (three dots access upper than upper,and so on). Now we run
main.py, the interpreter will say:
ValueError:attempted relative import beyond top-level package. The “top-level package” at here is
main.py. Just because
config.py is beside
main.py, they are at same hierarchy,
config.py isn’t “under”
main.py, or it isn’t “leaded” by
main.py, so it is beyond
main.py. To fix this, the simplest way is:
project package_1 module_1.py module_2.py config.py config.ini main.py
I think that is coincide with the principle of arrange project file hierarchy, you should arrange modules with different function in different folders, and just leave a top caller in the outside, and you can import how ever you want.
Simply you can use:
from Desktop.filename import something
given that the file is name
Users/user/Desktop, and will import everthing.
from Desktop.test import *
But make sure you make an empty file called “
__init__.py” in that directory
This also works, and is much simpler than anything with the
with open("C:/yourpath/foobar.py") as f: eval(f.read())