Categories
python python-import python-module

How do I import a module given the full path?

1592

How do I load a Python module given its full path?

Note that the file can be anywhere in the filesystem.

7

  • 116

    Nice and simple question – and useful answers but they make me wonder what happened with the python mantra “There is one obvious way” to do it.. It doesn’t seem like anything like a single or a simple and obvious answer to it.. Seems ridiculously hacky and version-dependent for such a fundamental operation (and it looks and more bloated in newer versions..).

    – inger

    Dec 6, 2019 at 12:08

  • 47

    @inger what happened with the python mantra “There is one obvious way” to do it […] [not] a single or a simple and obvious answer to it […] ridiculously hacky[…] more bloated in newer versions Welcome to the terrible world of python package management. Python’s import, virtualenv, pip, setuptools whatnot should all be thrown out and replaced with working code. I just tried to grok virtualenv or was it pipenv and had to work thru the equivalent of a Jumbo Jet manual. How that contrivance is paraded as The Solution to dealing with deps totally escapes me.

    Jun 26, 2020 at 20:59


  • 48

    relevant XKCD xkcd.com/1987

    Jun 26, 2020 at 21:08

  • 2

    @JohnFrazer it’s been made worse by constant nagging of people who couldn’t be bothered to read 2 paragraphs of documentation. Your XKCD isn’t really relevant, as it shows what these kinds of people can achieve when trying things until something works. Also, just because there’s a new way doesn’t mean there’s now “two obvious ways”. The old way is obvious for some cases, the new way introduces ease of use to other. That’s what happens when you actually care about DevX.

    Dec 2, 2020 at 0:13


  • 7

    And think that Java or even PHP (these days) have clear and simple way of splitting things in packages/namespaces and reuse it. It’s a shock to see such pain in Python which adopted simplicity in every other aspect.

    – Alex

    Jan 27, 2021 at 7:46

1619

For Python 3.5+ use (docs):

import importlib.util
import sys
spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
foo = importlib.util.module_from_spec(spec)
sys.modules["module.name"] = foo
spec.loader.exec_module(foo)
foo.MyClass()

For Python 3.3 and 3.4 use:

from importlib.machinery import SourceFileLoader

foo = SourceFileLoader("module.name", "/path/to/file.py").load_module()
foo.MyClass()

(Although this has been deprecated in Python 3.4.)

For Python 2 use:

import imp

foo = imp.load_source('module.name', '/path/to/file.py')
foo.MyClass()

There are equivalent convenience functions for compiled Python files and DLLs.

See also http://bugs.python.org/issue21436.

41

  • 77

    If I knew the namespace – ‘module.name’ – I would already use __import__.

    Aug 10, 2009 at 21:54

  • 71

    @SridharRatnakumar the value of the first argument of imp.load_source only sets the .__name__ of the returned module. it doesn’t effect loading.

    – Dan D.

    Dec 14, 2011 at 4:51

  • 21

    @DanD. — the first argument of imp.load_source() determines the key of the new entry created in the sys.modules dictionary, so the first argument does indeed affect loading.

    Apr 21, 2013 at 16:32

  • 24

    @AXO and more to the point one wonders why something as simple and basic as this has to be so complicated. It isn’t in many many other languages.

    – rocky

    May 22, 2016 at 17:04

  • 6

    @Mahesha999 Because importlib.import_module() does not allow you to import modules by filename, which is what the original question was about.

    Sep 28, 2016 at 12:50

532

The advantage of adding a path to sys.path (over using imp) is that it simplifies things when importing more than one module from a single package. For example:

import sys
# the mock-0.3.1 dir contains testcase.py, testutils.py & mock.py
sys.path.append('/foo/bar/mock-0.3.1')

from testcase import TestCase
from testutils import RunTests
from mock import Mock, sentinel, patch

13

  • 19

    How do we use sys.path.append to point to a single python file instead of a directory?

    – Phani

    Jan 13, 2014 at 17:46

  • 32

    🙂 Perhaps your question would be better suited as a StackOverflow question, not a comment on an answer.

    Mar 6, 2015 at 0:12

  • 4

    The python path can contain zip archives, “eggs” (a complex kind of zip archives), etc. Modules can be imported out of them. So the path elements are indeed containers of files, but they are not necessarily directories.

    – alexis

    Apr 30, 2015 at 21:21

  • 22

    Beware of the fact that Python caches import statements. In the rare case that you have two different folders sharing a single class name (classX), the approach of adding a path to sys.path, importing classX, removing the path and repeating for the reamaining paths won’t work. Python will always load the class from the first path from its cache. In my case I aimed at creating a plugin system where all plugins implement a specific classX. I ended up using SourceFileLoader, note that its deprecation is controversial.

    – ComFreek

    Jul 3, 2015 at 17:18


  • 4

    Note this approach allows the imported module to import other modules from the same dir, which modules often do, while the accepted answer’s approach does not (at least on 3.7). importlib.import_module(mod_name) can be used instead of the explicit import here if the module name isn’t known at runtime I would add a sys.path.pop() in the end, though, assuming the imported code doesn’t try to import more modules as it is used.

    – Eli_B

    May 6, 2019 at 21:45

107

To import your module, you need to add its directory to the environment variable, either temporarily or permanently.

Temporarily

import sys
sys.path.append("/path/to/my/modules/")
import my_module

Permanently

Adding the following line to your .bashrc (or alternative) file in Linux
and excecute source ~/.bashrc (or alternative) in the terminal:

export PYTHONPATH="${PYTHONPATH}:/path/to/my/modules/"

Credit/Source: saarrrr, another Stack Exchange question

3

  • 9

    This “temp” solution is a great answer if you want to prod a project around in a jupyter notebook elsewhere.

    – fordy

    Nov 16, 2018 at 17:20

  • But… it’s dangerous tampering with the path

    – Shai Alon

    Nov 10, 2019 at 15:56

  • 1

    @ShaiAlon You are adding paths, so no danger other than when you transfer codes from one computer to another, paths might get messed up. So, for package development, I only import local packages. Also, package names should be unique. If you are worried, use the temporary solution.

    Nov 13, 2019 at 0:11