如何从 python 控制台访问 python 包元数据?

问题描述 投票:0回答:7

如果我构建了一个使用

distutils.core
的 python 包,例如通过

setup(
    ext_package="foo",
    author="me",
    version="1.0",
    description="foo package",
    packages=["foo",],
)

所有元数据都去哪里了(它的用途是什么?)以及我如何从 python 中访问它。具体来说,在执行类似

的操作后,如何从 python 控制台访问作者信息
>>> import foo
python distutils python-packaging
7个回答
18
投票

随着 python3.8 的发布,您可能希望使用新的

importlib.metadata
[1] 模块来解析任何已安装包的元数据。

获取作者信息如下所示:

>>> from importlib import metadata
>>> metadata.metadata('foo')['Author']  # let's say you called your package 'foo'
'Arne'

获取安装版本:

>>> from importlib import metadata
>>> metadata.version('foo')
'0.1.0'

这比你以前必须做的要简单得多。


[1] 也可作为 Python2.7 和 3.5+ 的后向端口作为 importlib-metadata,感谢@ChrisHunt 指出这一点。


5
投票

访问元数据的一种方法是使用

import pip

package = [pckg for pckg in pip.get_installed_distributions() 
            if pckg.project_name == 'package_name'][0]
#  package var will contain some metadata: version, project_name and others.

pkg_resources

from pkg_resources import get_distribution

pkg = get_distribution('package_name')  # also contains a metadata

4
投票

元数据存储在

<package>-<version>-<py version>.egg-info
文件中。

当你创建你的模块时,你应该有这一行:

Writing /usr/lib/python2.7/site-packages/foobar-1.0-py2.7.egg-info

此文件包含元数据:

Metadata-Version: 1.0
Name: Foobar
Version: 1.0
Summary: foobar
Home-page: http://foobar.com/
Author: foobar
Author-email: [email protected]
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN

如果你想访问它,最好的方法是使用

pip
pkg_resources
(如 Alexander Zhukov 所说) 例如:

>>> import pkg_resources
>>> d = pkg_resources.get_distribution('Foobar')
>>> d.version
'1.0'
>>> d.location
'/usr/lib/python2.7/site-packages'

2
投票

仅关于

version
元数据,我发现使用各种可用的工具非常不可靠,因为它们中的大多数都不能涵盖所有情况。例如

  • 内置模块
  • 模块未安装但刚刚添加到 python 路径(例如通过您的 IDE)
  • 同一模块的两个版本可用(一个在 python 路径中取代安装的那个)

由于我们需要一种可靠的方法来获取 any 包、模块或子模块的版本,所以我最终编写了 getversion。使用起来非常简单:

from getversion import get_module_version
import foo
version, details = get_module_version(foo)

有关详细信息,请参阅文档


2
投票

解决方案

虽然我更喜欢使用

importlib.metadata
,因为已经有另一个答案展示了如何做到这一点,我会告诉你另一种选择。

出于说明的目的,我将使用我自己的一个包

genespeak
来自 PyPI。

metadata

try:
    from importlib import metadata
except ImportError:  # for Python<3.8
    import importlib_metadata as metadata

print(metadata.name('genespeak')) # genespeak
print(metadata.version('genespeak')) # 0.0.7

使用
pkginfo
PyPI

我们将使用以下5种方式获取包裹信息。

from pkginfo import SDist, BDist, Wheel, Installed, Develop

一个。从源分发中检查包信息

通常您会创建源分发文件:

python setup.py sdist

假设您在路径中有一个

.tar.gz
文件:
./dist/genespeak-0.0.7.tar.gz
,这是您需要提取包信息的内容。

from pkginfo import SDist

pkg = SDist("./dist/genespeak-0.0.7.tar.gz")
# Now you can access the metadata fields from 
# PKG-INFO file inside the source file:
# `./dist/genespeak-0.0.7.tar.gz`
print(pkg.name) # genespeak
print(pkg.version) # 0.0.7

乙。从二进制发行版中检查包信息

通常你会创建二进制分发文件(

.egg
):

python setup.py bdist_egg

假设您在路径中有一个

.egg
文件:
./dist/genespeak-0.0.7-py38.egg
,这是您需要提取包信息的内容。

from pkginfo import BDist

pkg = BDist("./dist/genespeak-0.0.7-py38.egg")
# Now you can access the metadata fields from 
# the binary distribution file (*.egg):
# `./dist/genespeak-0.0.7-py38.egg`
print(pkg.name) # genespeak
print(pkg.version) # 0.0.7

C。从 Wheel 中查看包裹信息

通常你会创建二进制分发轮文件(

.whl
):

python setup.py bdist_wheel

假设您在路径中有一个

.whl
文件:
./dist/genespeak-0.0.7-py3-none-any-whl
,这是您需要提取包信息的内容。

from pkginfo import Wheel

pkg = Wheel("./dist/genespeak-0.0.7-py3-none-any-whl")
# Now you can access the metadata fields from 
# PKG-INFO file inside the source file:
# `./dist/genespeak-0.0.7-py3-none-any.whl`
print(pkg.name) # genespeak
print(pkg.version) # 0.0.7

D.从已安装的包中检查包信息

查看这里了解更多详情

from pkginfo import Installed
import genespeak

pkg = Installed(genespeak)
# Now you can access the metadata fields from 
# PKG-INFO file inside the source file:
# `./dist/genespeak-0.0.7.tar.gz`
print(pkg.name) # genespeak
print(pkg.version) # 0.0.7

E。从开发目录中查看包信息

from pkginfo import Develop

dev = Develop(".")
# Now you can access the metadata fields from 
# PKG-INFO file under `genespeak.egg-info` 
# directory under the project root.
print(dev.name) # genespeak
print(dev.version) # 0.0.7

参考文献


1
投票

鉴于

setup.py
如下:

from distutils.core import setup

setup(
    name         = 'TestApp',
    version      = '0.0.1',
    author       = 'saaj',
    py_modules   = ['app'],
    test_suite   = 'test'
)

对于一些没有安装包的脚本和自动化,其中

pip
easy_install
甚至
setuptools
不提供命令行选项或公共 API 来读取所有元数据(例如
test_suite
),这里有一些 hacky 方式:

python3 -c "import sys, types; m = types.ModuleType('distutils.core'); \
    m.setup = lambda **kwargs: print(kwargs); \
    sys.modules['distutils.core'] = m; import setup" 

这将打印传递给

dict
的关键字参数的
setup()

{'author': 'saaj', 'version': '0.0.1', 'name': 'TestApp', 
    'test_suite': 'test', 'py_modules': ['app']}

您可以将

print
中的
lambda
替换为您需要的任何输出。如果您的
setup.py
setup()
导入
setuptools
,这实际上是推荐的方式,只需在代码段中将“distutils.core”替换为“setuptools”。

格式化片段如下:

import sys
import types

m = types.ModuleType('distutils.core')
m.setup = lambda **kwargs: print(kwargs)
sys.modules['distutils.core'] = m

import setup  # import you setup.py with mocked setup()

-2
投票

此数据的一个用途是,如果您要在 Pypi (http://pypi.python.org/) 上发布您的包,它就会显示在 Pypi 上。一种构造它的方法是这样的:

在您的

foo
模块的顶层:

__author__= "me"
__version__= "1.0"
__description__= "foo package"

setup.py

import foo
setup(

    author = foo.__author__,
    version = foo.__version__,
    description = foo.__description__,
    packages = ["foo",],

)

这样你只需要在一个地方更新你的元数据,因为数据是在你的包主模块中定义的,所以可以从那里访问它。

© www.soinside.com 2019 - 2024. All rights reserved.