48

I've seen several approaches for finding the path of a module by first importing it. Is there a way to do this without importing the module?

jeffcook2150
  • 3,920
  • 4
  • 38
  • 51
  • Why? Why don't you want to import it? – user225312 Jan 14 '11 at 16:53
  • 9
    Because importing is useless at the point in the program where the paths are needed and can cause circular dependencies and other issues. Import occurs at a more opportune time later down the road. – jeffcook2150 Jan 14 '11 at 17:00
  • 1
    Also you may want to just look at the source code without actually running any code in the module. – BrockLee Feb 27 '17 at 20:45

3 Answers3

67

Using pkgutil module:

>>> import pkgutil
>>> package = pkgutil.get_loader("pip")
>>> package.filename
'/usr/local/lib/python2.6/dist-packages/pip-0.7.1-py2.6.egg/pip'
>>> package = pkgutil.get_loader("threading")
>>> package.filename
'/usr/lib/python2.6/threading.py'
>>> package = pkgutil.get_loader("sqlalchemy.orm")
>>> package.filename
'/usr/lib/pymodules/python2.6/sqlalchemy/orm'

Using imp module:

>>> import imp
>>> imp.find_module('sqlalchemy')
(None, '/usr/lib/pymodules/python2.6/sqlalchemy', ('', '', 5))
>>> imp.find_module('pip')
(None, '/usr/local/lib/python2.6/dist-packages/pip-0.7.1-py2.6.egg/pip', ('', '', 5))
>>> imp.find_module('threading')
(<open file '/usr/lib/python2.6/threading.py', mode 'U' at 0x7fb708573db0>, '/usr/lib/python2.6/threading.py', ('.py', 'U', 1))

N.B: with imp module you can't do something like imp.find_module('sqlalchmy.orm')

mouad
  • 63,741
  • 17
  • 112
  • 105
  • @cgohlke : actually their is no __pkutil__ package, it should be __pkgutil__, it was a typo mistake , thanks for pointing it out :) – mouad Jan 14 '11 at 18:46
  • @mouad I'm actually looking for the same thing. The above implementation with `pkgutil` doesn't do what is requested in all cases. `pkgutil.get_laoder("sqlalchemy.orm")` wll execute `sqlalchemy/__init__.py`, tho it won't execute `sqlalchemy/orm.py`. – Prody Jul 14 '12 at 18:46
  • 2
    @Prody: Yes that's true in case of a package it will execute the ``__init__.py`` package as the documentation (http://docs.python.org/release/3.1.5/library/pkgutil.html#pkgutil.get_loader) say **If the named module is not already imported, its containing package (if any) is imported, in order to establish the package __path__** which make total sense :) – mouad Jul 14 '12 at 22:33
  • 11
    I found [in Python 3.5.1] that package.filename didn't exist, but package.get_filename() did. – Oddthinking Oct 25 '16 at 02:30
14

For python3 imp is deprecated. Use pkgutil (as seen above) or for Python 3.4+ use importlib.util.find_spec:

>>> import importlib
>>> spec = importlib.util.find_spec("threading")
>>> spec.origin
'/usr/lib64/python3.6/threading.py'
Bryce Guinta
  • 3,022
  • 1
  • 35
  • 33
  • spec.origin attribute do not exist for a module folder which contains an `__init__.py`. Use instead : ```python >>> spec.submodule_search_locations[0] ``` – Cyril Waechter Jan 15 '21 at 10:39
  • 1
    unfortunately `find_spec` might try importing the module https://github.com/python/cpython/blob/ec2385e315fc6b28d92dfb4c97fefcbb1e7daa68/Lib/importlib/util.py#L94 – karlicoss Feb 19 '21 at 01:04
1

You might want to try running this in your interpreter:

>>> import sys
>>> sys.modules['codecs'].__file__ # codecs is just an example
'/usr/lib/python2.7/codecs.pyc'
Noctis Skytower
  • 20,251
  • 16
  • 75
  • 111
virhilo
  • 6,026
  • 1
  • 27
  • 26