Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对于给定的模块,如何查找python包元数据信息_Python_Python Importlib - Fatal编程技术网

对于给定的模块,如何查找python包元数据信息

对于给定的模块,如何查找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

我试图检索给定模块名称的python包的元数据信息

我可以使用importlib元数据来检索信息,但在某些情况下,顶级模块名与包名不同

例如:

>>> 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