问题
If I have built a python package employing distutils.core
, e.g. via
setup(
ext_package="foo",
author="me",
version="1.0",
description="foo package",
packages=["foo",],
)
where does all the metadata go (what is it intended for?) and how can I access it from within python. Specifically, how can I access the author information from the python console after doing something like
>>> import foo
回答1:
One way to access the metadata is to use pip:
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.
or pkg_resources
from pkg_resources import get_distribution
pkg = get_distribution('package_name') # also contains a metadata
回答2:
The metadata are stored inside the <package>-<version>-<py version>.egg-info
file.
when you create your module, you should have this line :
Writing /usr/lib/python2.7/site-packages/foobar-1.0-py2.7.egg-info
This file contain the Metadata :
Metadata-Version: 1.0
Name: Foobar
Version: 1.0
Summary: foobar
Home-page: http://foobar.com/
Author: foobar
Author-email: foobar@foobar.net
License: UNKNOWN
Description: UNKNOWN
Platform: UNKNOWN
If you want to access it, the best way is with pip
or pkg_resources
(as said Alexander Zhukov)
ex :
>>> import pkg_resources
>>> d = pkg_resources.get_distribution('Foobar')
>>> d.version
'1.0'
>>> d.location
'/usr/lib/python2.7/site-packages'
回答3:
Concerning the version
metadata only, I found it quite unreliable to use the various tools available as most of them do not cover all cases. For example
- built-in modules
- modules not installed but just added to the python path (by your IDE for example)
- two versions of the same module available (one in python path superseding the one installed)
Since we needed a reliable way to get the version of any package, module or submodule, I ended up writing getversion. It is quite simple to use:
from getversion import get_module_version
import foo
version, details = get_module_version(foo)
See the documentation for details.
回答4:
One use of this data is that it is displayed on Pypi (http://pypi.python.org/) if you were to publish your package there. One way to structure it is like so:
in the top level of your foo
module:
__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",],
)
This way you only need to update your metadata in one place, and as the data is defined in your packages main module, it will be accessible from there.
回答5:
Given setup.py
as follows:
from distutils.core import setup
setup(
name = 'TestApp',
version = '0.0.1',
author = 'saaj',
py_modules = ['app'],
test_suite = 'test'
)
For some scripting and automation without installing the package, where pip
, easy_install
and even setuptools
don't provide command line options or public APIs for reading all metadata (e.g. test_suite
), here's a little hacky way:
python3 -c "import sys, types; m = types.ModuleType('distutils.core'); \
m.setup = lambda **kwargs: print(kwargs); \
sys.modules['distutils.core'] = m; import setup"
This will print a dict
of keyword arguments passed to setup()
.
{'author': 'saaj', 'version': '0.0.1', 'name': 'TestApp',
'test_suite': 'test', 'py_modules': ['app']}
You can replace print
in the lambda
to whatever output you need. If your setup.py
imports setup()
from setuptools
, which is actually the recommended way, just replace "distutils.core" with "setuptools" in the snippet.
Formatted snippet follows:
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:
With python3.8 around the corner, you might want to use the new importlib.metadata module to parse any installed package's metadata.
Getting the author information would look like this:
>>> from importlib import metadata
>>> metadata.metadata('foo')['Author']
'me'
Which is a lot more straight forward than the former ways.
来源:https://stackoverflow.com/questions/20683118/how-to-access-python-package-metadata-from-within-the-python-console