2013-12-19 49 views
9

如果我已经构建了一个使用distutils.core的Python包,通过如何从python控制台访问python包元数据?

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

在哪里所有的元数据去(它的目的是什么?)以及如何从python中访问它。具体来说,我怎样才能做这样的事情来访问元数据

>>> import foo 

回答

4

的一种方式后访问从Python控制台作者信息是使用

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',所以无法测试它的'pkg_resources.get_distribution'。做法似乎并没有工作,要么因为这是通过一个简单的'蟒蛇setup.py build'安装一个扩展在这种情况下,我得到一个'DistributionNotFound:。foo'例外 – dastrobu

+1

蟒蛇setup.py构建不安装使用 –

+2

。 '的增加pip'在进口时的巨大延迟,并增加了大量的内存占用自己的代码它在内部又是用'pkg_resources'和渔网你相同的结果。基本上,这里'是pip'无关和误导“的解决方案”。答案也没有得到所需的信息;从'Distribution'对象这是非常不明显的如何获取版本,作者和描述,其中包括其他领域,退了出去。 '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 

如果您要访问它,最好的方法是用pippkg_resources(如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

失踪需要步骤实际读回的元数据:'d._get_metadata(d.PKG_INFO)'裸分配对象具有访问信息的没有特别明显的方式。 – amcgregor

0

这个数据的一个用途是它显示在Pypi(http://pypi.python.org/)上,如果你要在那里发布你的包。构建它的一种方式是像这样:

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

setup.py

import foo 
setup(

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

) 

这样,你只需要在一个更新元数据

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

对于一些脚本和自动化,无需安装包,其中pipeasy_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" 

这将打印传递给setup()关键字参数的dict

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

您可以替换lambda到你需要的任何输出print。如果您的setup.pysetuptools进口setup(),这实际上是推荐的方式,只需替换“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()