解释Python入口点?

Bra*_*ght 167 python setuptools

我已经阅读了关于Pylons和Peak页面上的鸡蛋入口点的文档,我仍然不太明白.有人可以向我解释一下吗?

Pet*_*tri 182

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

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

举个例子,让我们使用一个函数的名称,以及一个带有完全限定名称'myns.mypkg.mymodule'的虚构python模块:

def the_function():
   "function whose name is 'the_function', in 'mymodule' module"
   print "hello from the_function"
Run Code Online (Sandbox Code Playgroud)

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

    entry_points = {
        'my_ep_group_id': [
            'my_ep_func = myns.mypkg.mymodule:the_function'
        ]
    },
Run Code Online (Sandbox Code Playgroud)

如示例所示,入口点被分组; 有相应的API来查找属于某个组的所有入口点(例如下面的例子).

在程序包安装(即运行'python setup.py install')时,setuptools会解析上述声明.然后它将解析的信息写入特殊文件.之后,pkg_resources API(setuptools的一部分)可用于查找入口点并访问具有相关名称的对象:

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()})
Run Code Online (Sandbox Code Playgroud)

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

假设同一组ID没有其他入口点注册,则调用the_function将很简单:

>>> named_objects['my_ep_func']()
hello from the_function
Run Code Online (Sandbox Code Playgroud)

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

  • 在所有这个过程中使用'my_ep_func'名称在哪里?它似乎没有被pkg_resources迭代器用于任何东西. (4认同)
  • @KamilKisiel:在这里用于说明的例子中,入口点的名称确实没有用于任何东西,也不需要它; 是否使用入口点的名称取决于应用程序.该名称仅可用作入口点实例的_name_属性. (2认同)
  • 我认为丢弃ep.name并将named_objects设置为列表而不是字典是令人困惑的,所以我编辑了答案。答案将显示在何处获取名称以及是否期望其为“ the_function”或“ my_ep_func”。否则,读者必须在其他地方找到其他文档。这是一个极好的答案,是我见过的entry_points的最短,最清晰的解释! (2认同)
  • 我在github上创建了一个演示这个概念的项目.https://github.com/RichardBronosky/entrypoint_demo (2认同)

Bra*_*des 155

"入口点"通常是Python包的开发人员或用户可能想要使用的函数(或其他可调用的函数式对象),尽管不可调用的对象也可以作为入口点提供(正确)在评论中指出!).

最流行的入口点是"console_script"入口点,它指向您希望作为命令行工具提供给安装程序包的任何人的函数.这进入你的setup.py,如:

entry_points={
    'console_scripts': [
        'cursive = cursive.tools.cmd:cursive_command',
    ],
},
Run Code Online (Sandbox Code Playgroud)

我有一个我刚刚部署的名为"cursive.tools"的软件包,我想让它提供一个"草书"命令,有人可以从命令行运行,如:

$ cursive --help
usage: cursive ...
Run Code Online (Sandbox Code Playgroud)

这样做的方法是定义一个函数,就像cursive/tools/cmd.py中的"cursive_command"函数看起来像:

def cursive_command():
    args = sys.argv[1:]
    if len(args) < 1:
        print "usage: ..."
Run Code Online (Sandbox Code Playgroud)

等等; 它应该假设它是从命令行调用的,解析用户提供的参数,并且......好吧,做任何命令设计要做的事情.

安装docutils包是一个很好的入口点使用示例:它将安装类似于六个有用的命令,用于将Python文档转换为其他格式.

  • 当前的docutils的`setup.py`根本不包含`entry_points`. (3认同)
  • 这是一个很好的答案,因为它展示了共享单个entry_point组名称的多个项目的强大功能,即"console_scripts".将此答案与Petri的更一般答案进行比较.您将看到setuptools必须使用此pkg_resources机制来获取console_scripts,然后围绕它们创建一个shell包装器.激励?使用这些.它们不仅仅是console_scripts的好处. (2认同)

Ric*_*and 16

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

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

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