Python安装——如何将一个模块作为另一个模块的子模块安装?

5

我希望创建一个包作为扩展安装到另一个Python包的子模块中。

基本上,原始模块的设置如下:

origmodule/
    __init__.py
    stuff.py
    ext/
        __init__.py
        # This module is empty

然后将我的扩展模块安装到空的origmodule.ext模块中。阅读distutils的说明并不清楚是否支持或者可能实现这一点。最终目标是,一旦安装了我的扩展模块,可以这样导入:

import origmodule.ext.my_extension

1个回答

5
你不能使用setuptools在另一个包内安装,这是不被支持的。
相反,你需要使用入口点。你的origmodule应该查找所有为特定键注册的入口点,而你的extension模块应该为该键注册自己。
你的扩展程序注册了一个扩展点:
entry_points={
    'some.opaque.string.unique.to.origmodule':
        ['my_extension = my.extension.package:some.entry.point', ]
}

你的 origmodule 可以通过询问 pkg_resources 来发现这个内容:

import pkg_resources

for entrypoint in pkg_resources.iter_entry_points(group='some.opaque.string.unique.to.origmodule'):
    extension = entrypoint.load()

请看Babel项目作为例子。Babel可以从文件中提取可翻译的文本;它知道如何在Python源代码中执行此操作,但它也支持可以从其他格式中提取此类文本的扩展。
这样的提取方法可以注册为扩展点。Babel在编写提取方法部分记录了这一点。当提取文本时,消息提取代码会加载这些入口点
GROUP_NAME = 'babel.extractors'

# ...

for entry_point in working_set.iter_entry_points(GROUP_NAME,
                                                 method):
    func = entry_point.load(require=True)
    break

Mako模板语言提供了这样一个插件;它注册入口点,该入口点指向实际实现

[babel.extractors]
mako = mako.ext.babelplugin:extract

def extract(fileobj, keywords, comment_tags, options):
    # ...

我不太清楚 some.opaque.string.unique.to.origmodule 是什么意思?这只是我为扩展选择的名称吗?任何第三方或其他模块都可以使用该名称进行注册吗?如果是这样,那么这个名称是否需要在我的应用程序中是唯一的?例如,如果某个其他软件包使用相同的名称,那么该软件包是否会尝试导入我的扩展? - john-charles
是的,这只是您选择的名称,这就是不透明字符串的意思。 :-) 如果另一个包使用相同的名称,它也会自然地加载相同的入口点。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接