Как получить доступ к метаданным пакета python из консоли python?

Если я создал пакет python с использованием distutils.core, например. с помощью

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

где все метаданные идут (для чего это предназначено?) и как я могу получить к нему доступ изнутри python. В частности, как я могу получить доступ к информации об авторе с консоли python после выполнения чего-то вроде

>>> import foo

Ответ 1

Один из способов доступа к метаданным - использовать :

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

Ответ 2

Метаданные хранятся внутри файла <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 (как сказал Александр Жуков) ex:

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

Ответ 3

Что касается только метаданных version, я нашел довольно ненадежным использование различных доступных инструментов, поскольку большинство из них не охватывает все случаи. Например

  • встроенные модули
  • модули не установлены, а просто добавлены в путь к Python (например, вашей IDE)
  • доступны две версии одного и того же модуля (одна в пути Python заменяет установленную)

Так как нам нужен был надежный способ получить версию любого пакета, модуля или субмодуля, я закончил писать getversion. Это довольно просто использовать:

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

Смотрите документацию для деталей.

Ответ 4

Одно использование этих данных состоит в том, что оно отображается на Pypi (http://pypi.python.org/), если вы собираетесь опубликовать там свой пакет. Один из способов его структурирования выглядит так:

на верхнем уровне вашего модуля 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",],

)

Таким образом вам нужно только обновить метаданные в одном месте, а так как данные определены в главном модуле пакетов, он будет доступен оттуда.

Ответ 5

Учитывая 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), здесь немного хакерский путь:

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

Ответ 6

С python3.8 за углом вы можете использовать новый модуль importlib.metadata для анализа метаданных любого установленного пакета.

Получение информации об авторе будет выглядеть так:

>>> from importlib import metadata
>>> metadata.metadata('foo')['Author']
'me'

Что намного проще, чем прежние способы.