Reputation: 4226
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?
Upvotes: 66
Views: 18327
Reputation: 656
import importlib.util
import os
this_module='numpy'
origin=importlib.util.find_spec(this_module).origin
print(origin)
path_to_this_module=os.path.dirname(origin)
print(path_to_this_module)
Output on windows:
...\site-packages\numpy\__init__.py
...\site-packages\numpy
Output on linux:
/home/.../site-packages/numpy/__init__.py
/home/.../site-packages/numpy
Upvotes: 0
Reputation: 20245
For most use-cases, you actually don't need help from third parties. importlib.util.find_spec
has been around since python3.4, and solves the issue for top-level imports:
>>> import importlib.util
>>> spec = importlib.util.find_spec("foo")
>>> spec.origin
/home/me/my_venv/python3.11/site-packages/foo/__init__.py
And for a portable variant that gets the parent folder:
[...]
>>> from pathlib import Path
>>> Path(spec.origin).parent
/home/me/my_venv/python3.11/site-packages/foo
Notes:
foo.bar
), parent packages will be actually imported. Due to the dynamic nature of python, including how imports may resolve, there is no correct solution which does not do an actual import (try to find the location of os.path
without importing os
for a real-world-example).spec
will be None
.spec.origin
will be None
Upvotes: 1
Reputation: 70089
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'
In Python 3, use pkgutil.get_loader("module name").get_filename()
instead.
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')
Upvotes: 72
Reputation: 3752
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'
Upvotes: 20
Reputation: 6793
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'
Upvotes: -1