2013-12-19 14 views
9

Wenn ich ein Python-Paket unter Verwendung distutils.core, z. überWie auf Python-Paket-Metadaten innerhalb der Python-Konsole zugreifen?

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

Wohin gehen alle Metadaten (für was ist es gedacht?) und wie kann ich von Python darauf zugreifen? Genauer gesagt, wie kann ich die Informationen über den Autor aus der Python-Konsole zugreifen, nachdem so etwas wie

>>> import foo 

Antwort

4

Eine Möglichkeit, tun die Metadaten zugreifen verwenden :

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. 

oder pkg_resources

from pkg_resources import get_distribution 

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

Leider habe ich nicht' pip' jetzt installiert, so dass es nicht testen kann die 'pkg_resources.get_distribution'. approach scheint nicht für eine Erweiterung zu funktionieren, die über ein einfaches 'python setup.py build' installiert wurde.In diesem Fall erhalte ich eine' DistributionNotFound: foo' Ausnahme. – dastrobu

+1

python setup.py build installiert nicht. –

+2

Verwendung von 'pip' fügt eine enorme Verzögerung zum Zeitpunkt des Imports hinzu und fügt Ihrem eigenen Code einen beträchtlichen Speicherbedarf hinzu.Innerhalb verwendet es nur' pkg_resources' und führt Sie zu einem identischen Ergebnis; im Grunde ist 'pip' hier irrelevant und a irreführende "Lösung ". Die Antwort erhält auch nicht die gewünschte Information; Von einem "Distribution" -Objekt ist es extrem nicht offensichtlich, wie Version, Autor und Beschreibung unter den anderen Feldern wieder herauskommen. 'pkg._get_metadata (pkg.PKG_INFO)' liefert Ihnen die ersten Zeilen aus der Metadatendatei als Liste. – amcgregor

2

Die Metadaten sind in der Datei <package>-<version>-<py version>.egg-info gespeichert.

, wenn Sie Ihr Modul erstellen, sollten Sie diese Zeile haben:

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

Diese Datei enthält die Metadaten:

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 

Wenn Sie darauf zugreifen wollen, ist der beste Weg, pip oder pkg_resources (wie gesagt Alexander Zhukov) ex:

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

Fehlender Schritt zum tatsächlichen Zurücklesen der Metadaten: 'd.get_metadata (d.PKG_INFO)' Das nackte Distributionsobjekt hat keine besonders offensichtliche Möglichkeit, auf die Informationen zuzugreifen. – amcgregor

0

Eine Verwendung dieser Daten ist, dass es auf Pypi (http://pypi.python.org/) angezeigt wird, wenn Sie Ihr Paket dort veröffentlichen würden. Eine Möglichkeit, es zu strukturieren ist etwa so:

in der obersten Ebene Ihres foo Modul:

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

in setup.py:

import foo 
setup(

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

) 

Auf diese Weise brauchen Sie nur Ihre Metadaten in einer aktualisieren platzieren, und da die Daten in Ihrem Paket-Hauptmodul definiert sind, ist es von dort aus zugänglich.

+1

Hier ist eine lebenswichtige Fang-22. Ihr Setup-Skript hängt nun davon ab, dass das installierte Paket bereits installiert (oder zumindest bereits importiert) ist. Das ist keine gute Sache. (Down-Stimme für potenziell gefährliche Praxis.) – amcgregor

0

Gegeben setup.py wie folgt:

from distutils.core import setup 

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

Für einige Scripting und Automatisierung ohne das Paket zu installieren, wo pip, easy_install und sogar setuptools nicht Befehlszeilenoptionen oder öffentliche APIs zum Lesen aller Metadaten (zB test_suite liefern können hier ist), ein wenig hacky Weg:

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

Dies wird eine dict von Keyword-Argumente drucken zu setup() geben.

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

Sie können print im lambda ersetzen, was auch immer Ausgabe, die Sie benötigen. Wenn Ihre setup.py importiert setup() von setuptools, die eigentlich die empfohlene Methode ist, ersetzen Sie einfach "distutils.. Kern“mit "Setuptools" im Snippet

Formatiert Schnipsel folgt:

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