2013-12-19 6 views
9

Если я создал пакет python с использованием distutils.core, например. черезКак получить доступ к метаданным пакета python из консоли python?

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

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

>>> import foo 

ответ

4

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

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

К сожалению, у меня нет' pip' установлен прямо сейчас, поэтому он не может проверить его 'The pkg_resources.get_distribution'. подход не работает ни для расширения, которое было установлено с помощью простой 'python setup.py build'. В этом случае я получаю исключение' DistributionNotFound: foo'. – dastrobu

+1

python setup.py build не устанавливается. –

+2

Использование «pip» добавляет огромную задержку во время импорта и добавляет существенный объем памяти к вашему собственному коду. Он внутренне просто использует 'pkg_resources' и сдает вам одинаковый результат, в основном« pip »здесь посторонний и вводящее в заблуждение "решение ». Ответ также фактически не получает желаемой информации; из объекта «Распространение» крайне неочевидно, как получить версию, автора и описание среди других полей. 'pkg._get_metadata (pkg.PKG_INFO)' выдает вам отдельные строки из файла метаданных в качестве списка для стартеров. – amcgregor

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' 
+1

Отсутствует необходимый шаг для фактического считывания метаданных: 'd._get_metadata (d.PKG_INFO)' Объект открытого распространения не имеет особо очевидного способа доступа к информации. – amcgregor

0

Одно из этих данных заключается в том, что оно отображается на 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",], 

) 

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

+1

Здесь есть жизненно важный улов-22. Теперь ваш скрипт установки зависит от установленного пакета (или, по крайней мере, уже импортируемого). Это нехорошо. (Проголосовать за потенциально опасную практику.) – amcgregor

0

Учитывая 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.. Ядро»с "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() 
Смежные вопросы