对于给定的模块,如何查找python包元数据信息
我试图检索给定模块名称的python包的元数据信息 我可以使用importlib元数据来检索信息,但在某些情况下,顶级模块名与包名不同 例如:对于给定的模块,如何查找python包元数据信息,python,python-importlib,Python,Python Importlib,我试图检索给定模块名称的python包的元数据信息 我可以使用importlib元数据来检索信息,但在某些情况下,顶级模块名与包名不同 例如: >>> importlib_metadata.metadata('zmq')['License'] Traceback (most recent call last): File "<stdin>", line 1, in <module> File "c:\Users\xxxxx\AppData\Loc
>>> importlib_metadata.metadata('zmq')['License']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\Users\xxxxx\AppData\Local\Programs\Python\Python37\Lib\site-packages\importlib_metadata\__init__.py", line 499, in metadata
return Distribution.from_name(distribution_name).metadata
File "c:\Users\xxxxx\AppData\Local\Programs\Python\Python37\Lib\site-packages\importlib_metadata\__init__.py", line 187, in from_name
raise PackageNotFoundError(name)
importlib_metadata.PackageNotFoundError: zmq
>>> importlib_metadata.metadata('pyzmq')['License']
'LGPL+BSD'
>>importlib_metadata.metadata('zmq')['License']
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
元数据中的文件“c:\Users\xxxxx\AppData\Local\Programs\Python\37\Lib\site packages\importlib\u metadata\uuuuu init\uuuuuu.py”,第499行
返回Distribution.from_name(Distribution_name).metadata
文件“c:\Users\xxxxx\AppData\Local\Programs\Python\37\Lib\site packages\importlib\u metadata\uuuuuu init\uuuuuu.py”,第187行,在from\u name中
raise PackageNotFoundError(名称)
importlib_metadata.PackageNotFoundError:zmq
>>>importlib_metadata.metadata('pyzmq')['License']
“LGPL+BSD”
我相信下面的方法应该可以奏效:
#!/usr/bin/env python3
import importlib.util
import pathlib
import importlib_metadata
def get_distribution(file_name):
result = None
for distribution in importlib_metadata.distributions():
try:
relative = (
pathlib.Path(file_name)
.relative_to(distribution.locate_file(''))
)
except ValueError:
pass
else:
if relative in distribution.files:
result = distribution
return result
def alpha():
file_name = importlib.util.find_spec('easy_install').origin
distribution = get_distribution(file_name)
print("alpha", distribution.metadata['Name'])
def bravo():
file_name = importlib_metadata.__file__
distribution = get_distribution(file_name)
print("bravo", distribution.metadata['Name'])
if __name__ == '__main__':
alpha()
bravo()
更新(2021年2月): 由于
importlib\u metadata
中新添加的packages\u distributions()
函数,看起来这可能会变得更容易:
- 我相信这是一个可以满足您需求的函数。它的效率不是很高,因为它必须枚举所有已安装的软件包发行版,并读取每个发行版的顶级模块列表——然而,我相信这是最好的方法。(当然,您还可以缓存从顶级模块名到包名的dict映射。)
来自importlib.metadata导入分发,分发
从pathlib导入路径
从键入导入*
def get_pkg_分发(顶级模块:str)->可选[分发]:
pkg_path=路径(_文件)。父
对于分发中的dist():
package_namespaces=(dist.read_text(“top_level.txt”)或“”).splitlines()
如果包名称空间中的顶级模块:
返回区
一无所获
#获取当前包的包元数据。请注意,“包”实际上是顶级模块的名称!
pkg\u metadata=dict(获取pkg\u分发(\uuuu package\uuuu).metadata.items())
__版本=打包元数据[“版本”]
Some ideas:--对于经过这里(通过谷歌等)的其他人,请查看[其他讨论][1],了解更多基于@sinoroc建议的想法。[1] :这假设顶级模块的路径是包的子目录。zmq和pyzmq-.dist info都是站点包的子目录。@nsk我不理解这个问题。作为一个测试,我刚刚安装了pyzmq
,上面的代码似乎工作得非常好。@nsk回答了您的问题,还是还需要一些澄清?很好的解决方案。我要补充的唯一一件事是,有一个is_relative_to
方法可以稍微简化一些事情。我说得太快了:不幸的是,因为在/usr/local/lib/python3.9/site-packages/中有这么多的包只是鸡蛋,所以这个方法失败了。这个解决方案似乎和我的有同样的缺点。因为它依赖于文件名。最好依赖完全限定的模块名,获取顶级包/模块名,然后与比较。实际上,我的解决方案非常类似于packages\u发行版的实现
,只查看了该库的源代码!我相信\u包
应该获得顶级模块的完整限定名?但不是100%确定。这个技巧对我有用吗。它对安装为egg或类似的代码有效吗?我上次尝试时似乎是这样的。。。但我可以稍后再进行适当的调查。是的,如果你能设法进行测试,请告诉我。我真的很想知道如何从一个鸡蛋里得到一个有效的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
。