我见过几种通过首先导入模块来查找其路径的方法。是否有一种方法可以在不导入模块的情况下完成这个任务?
我见过几种通过首先导入模块来查找其路径的方法。是否有一种方法可以在不导入模块的情况下完成这个任务?
使用pkgutil模块:
>>> 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'
在Python 3中,使用pkgutil.get_loader("模块名").get_filename()
代替。
使用imp模块:
>>> 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))
注意:使用imp模块,你无法像这样做:imp.find_module('sqlalchmy.orm')
pkgutil
的上述实现并不能在所有情况下满足要求。pkgutil.get_laoder("sqlalchemy.orm")
会执行 sqlalchemy/__init__.py
,但不会执行 sqlalchemy/orm.py
。 - Prodyos.py
(os标准库)的位置? - tamuhey对于Python3,imp
已经被弃用。请使用pkgutil(如上所示)或者对于Python 3.4+,请使用importlib.util.find_spec:
>>> import importlib
>>> spec = importlib.util.find_spec("threading")
>>> spec.origin
'/usr/lib64/python3.6/threading.py'
__init__.py
,因此 spec.origin
属性不存在。请改用以下代码:>>> spec.submodule_search_locations[0]
- Cyril Waechterfind_spec
可能会尝试导入模块 https://github.com/python/cpython/blob/ec2385e315fc6b28d92dfb4c97fefcbb1e7daa68/Lib/importlib/util.py#L94 - karlicossfind_spec
来查找子模块时,这才有效:find_spec("foo")
不会导入任何内容,但是find_spec("foo.bar")
会导入foo
(从而评估foo.__init__.py
)。 - JustinBull对于大多数用例,实际上您不需要第三方的帮助。importlib.util.find_spec
自Python3.4以来就存在,并解决了顶级导入的问题:
>>> import importlib.util
>>> spec = importlib.util.find_spec("foo")
>>> spec.origin
/home/me/my_venv/python3.11/site-packages/foo/__init__.py
如果需要一个可移植的变体来获取父文件夹:
[...]
>>> from pathlib import Path
>>> Path(spec.origin).parent
/home/me/my_venv/python3.11/site-packages/foo
注意事项:
foo.bar
),将实际导入父包。由于Python的动态性质,包括导入的解析方式,没有正确的解决方案不进行实际导入(尝试在不导入os
的情况下查找os.path
的位置作为真实世界示例)。spec
将为None
。spec.origin
将为None
>>> import sys
>>> sys.modules['codecs'].__file__ # codecs is just an example
'/usr/lib/python2.7/codecs.pyc'