解释Python入口点?

问题:解释Python入口点?

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

I’ve read the documentation on egg entry points in Pylons and on the Peak pages, and I still don’t really understand. Could someone explain them to me?


回答 0

“入口点”通常是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文档转换成其他格式的有用命令之类的东西。

An “entry point” is typically a function (or other callable function-like object) that a developer or user of your Python package might want to use, though a non-callable object can be supplied as an entry point as well (as correctly pointed out in the comments!).

The most popular kind of entry point is the console_scripts entry point, which points to a function that you want made available as a command-line tool to whoever installs your package. This goes into your setup.py like:

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

I have a package I’ve just deployed called “cursive.tools”, and I wanted it to make available a “cursive” command that someone could run from the command line, like:

$ cursive --help
usage: cursive ...

The way to do this is define a function, like maybe a “cursive_command” function in cursive/tools/cmd.py that looks like:

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

and so forth; it should assume that it’s been called from the command line, parse the arguments that the user has provided, and … well, do whatever the command is designed to do.

Install the docutils package for a great example of entry-point use: it will install something like a half-dozen useful commands for converting Python documentation to other formats.


回答 1

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软件开发提供了有用的工具。

EntryPoints provide a persistent, filesystem-based object name registration and name-based direct object import mechanism (implemented by the setuptools package).

They associate names of Python objects with free-form identifiers. So any other code using the same Python installation and knowing the identifier can access an object with the associated name, no matter where the object is defined. The associated names can be any names existing in a Python module; for example name of a class, function or variable. The entry point mechanism does not care what the name refers to, as long as it is importable.

As an example, let’s use (the name of) a function, and an imaginary python module with a fully-qualified name ‘myns.mypkg.mymodule’:

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

Entry points are registered via an entry points declaration in setup.py. To register the_function under entrypoint called ‘my_ep_func’:

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

As the example shows, entry points are grouped; there’s corresponding API to look up all entry points belonging to a group (example below).

Upon a package installation (ie. running ‘python setup.py install’), the above declaration is parsed by setuptools. It then writes the parsed information in special file. After that, the pkg_resources API (part of setuptools) can be used to look up the entry point and access the object(s) with the associated name(s):

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()})

Here, setuptools read the entry point information that was written in special files. It found the entry point, imported the module (myns.mypkg.mymodule), and retrieved the_function defined there, upon call to pkg_resources.load().

Assuming there were no other entry point registrations for the same group id, calling the_function would then be simple:

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

Thus, while perhaps a bit difficult to grasp at first, the entry point mechanism is actually quite simple to use. It provides an useful tool for pluggable Python software development.


回答 2

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

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

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

From abstract point of view, entry points are used to create a system-wide registry of Python callables that implement certain interfaces. There are APIs in pkg_resources to see which entry points are advertised by a given package as well as APIs to determine which packages advertise a certain entry point.

Entry points are useful for allowing one package do use plugins that are in another package. For instance, Ian Bicking’s Paste project uses entry points extensively. In this case, you can write a package that advertises its WSGI application factory using the entry point paste.app_factory.

Another use for entry points is enumerating all the packages on the system that provide some plugin functionality. The TurboGears web framework uses the python.templating.engines entry point to look up templating libraries that are installed and available.