解释Python入口点?


181

我已经阅读了Pylons和Peak页面中有关蛋入口的文档,但我仍然不太了解。有人可以向我解释吗?

Answers:


168

“入口点”通常是Python包的开发人员或用户可能希望使用的函数(或其他可调用的类似函数的对象),尽管也可以提供非调用对象作为入口点(正确地在评论中指出!)。

最受欢迎的入口点是console_scripts入口点,它指向您想作为命令行工具提供给安装软件包的任何人的功能。这进入您的setup.py中,如下所示:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},

我有一个刚刚部署的名为“ cursive.tools”的软件包,我希望它提供一个可以使某些人可以从命令行运行的“ cursive”命令,例如:

$ cursive --help
usage: cursive ...

完成此操作的方法是定义一个函数,例如,cursive / tools / cmd.py中的“ cursive_command”函数如下所示:

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."

等等 它应该假定已从命令行调用了它,分析了用户提供的参数,然后...好,执行该命令旨在执行的所有操作。

安装docutils软件包是一个很好的切入点使用示例:它将安装诸如将六个Python文档转换成其他格式的有用命令之类的东西。


3
当前的文件setup.py不包含entry_points任何内容。
马特·威尔基

2
这是一个很好的答案,因为它演示了共享单个entry_point组名称(即“ console_scripts”)的多个项目的强大功能。将此答案与Petri的更一般的答案进行比较。您将看到setuptools必须使用此pkg_resources机制来获取console_scripts,然后在它们周围创建外壳包装。鼓舞人心?使用这些。它们不仅对console_scripts有好处。
布鲁诺·布鲁诺斯基

188

EntryPoints提供持久的,基于文件系统的对象名称注册和基于名称的直接对象导入机制(由setuptools实现)包实现)。

它们将Python对象的名称与自由格式的标识符相关联。因此,使用相同的Python安装并知道标识符的任何其他代码都可以访问具有关联名称的对象,无论该对象在何处定义。的相关联的名称可以是现有一个Python模块中的任何名称 ; 例如类,函数或变量的名称。入口点机制并不关心名称所指的是什么,只要它是可导入的即可。

例如,让我们使用一个函数(的名称)和一个假想的python模块,其全限定名称为“ myns.mypkg.mymodule”:

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"

入口点通过setup.py中的入口点声明进行注册。要在名为“ my_ep_func”的入口下注册the_function:

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },

如示例所示,入口点被分组。有相应的API可以查找属于一个组的所有入口点(下面的示例)。

安装软件包后(即运行“ python setup.py install”),setuptools将解析以上声明。然后将解析的信息写入特殊文件中。之后,可以使用pkg_resources APIsetuptools的一部分)来查找入口点并访问具有关联名称的对象:

import pkg_resources

named_objects = {}
for ep in pkg_resources.iter_entry_points(group='my_ep_group_id'):
   named_objects.update({ep.name: ep.load()})

在这里,setuptools读取写在特殊文件中的入口点信息。在调用pkg_resources.load()时,它找到了入口点,导入了模块(myns.mypkg.mymodule),并检索了其中定义的the_function。

假设没有相同组ID的其他入口点注册,那么调用the_function将很简单:

>>> named_objects['my_ep_func']()
hello from the_function

因此,虽然起初可能有点难以理解,但是入口点机制实际上非常易于使用。它为可插拔Python软件开发提供了有用的工具。


4
在所有此过程中,“ my_ep_func”名称在哪里使用?pkg_resources迭代器似乎没有将其用于任何用途。
卡米尔·基西尔

2
@KamilKisiel:在此处用于说明的示例中,入口点的名称确实没有用于任何东西,也不需要使用;入口点的名称是否用于任何事情取决于应用程序。名称可以简单地用作入口点实例的name属性。
Petri

3
我认为丢弃ep.name并将named_objects设置为列表而不是字典是令人困惑的,所以我编辑了答案。答案将显示在何处获取名称以及是否期望其为“ the_function”或“ my_ep_func”。否则,读者必须在其他地方找到其他文档。这是一个出色的答案,是我见过的entry_points的最短,最清晰的解释!
布鲁诺·布鲁诺斯基

3
我在github上创建了一个项目来演示这个概念。github.com/RichardBronosky/entrypoint_demo
Bruno Bronosky

1
这是对入口点的非常清晰的解释,请您为详细解释。该EntryPoints链接是陈旧的,虽然解释是很清楚的。
Rahul Nair

18

从抽象的角度来看,入口点用于创建实现特定接口的Python可调用对象的系统范围注册表。pkg_resources中有一些API可以查看给定程序包通告哪些入口点,以及可以确定哪些程序包通告某个入口点的API。

入口点对于允许一个软件包使用另一个软件包中的插件很有用。例如,Ian Bicking的Paste项目广泛使用入口点。在这种情况下,您可以编写一个使用入口点公布其WSGI应用程序工厂的包paste.app_factory

入口点的另一个用途是枚举系统上提供某些插件功能的所有软件包。该TurboGears的 Web框架使用python.templating.engines切入点来查找已安装并可用模板库。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.