::-- JinQing [2007-06-26 04:46:58]

23.2. C Embedding API Overview

23.2. C语言内嵌API概览 (JinQing 截稿 2007.6.26)

The first thing you should know about Python's embedded-call API is that it is less structured than the extension interfaces. Embedding Python in C may require a bit more creativity on your part than extending: you must pick tools from a general collection of calls to implement the Python integration instead of coding to a boilerplate structure. The upside of this loose structure is that programs can combine embedding calls and strategies to build up arbitrary integration architectures.

首先你应该了解的是,Python的内嵌接口并不像扩展接口那样结构化。比起扩展来,在C语言中内嵌Python可能需要你多一点创造性:你必须精心构造一系列调用来实现集成,而无法按固定结构编码。这种松散结构也有好处,就是程序可以组合内嵌调用与策略来构建任意的集成架构。

The lack of a more rigid model for embedding is largely the result of a less clear-cut goal. When extending Python, there is a distinct separation for Python and C responsibilities and a clear structure for the integration. C modules and types are required to fit the Python module/type model by conforming to standard extension structures. This makes the integration seamless for Python clients: C extensions look like Python objects and handle most of the work.

内嵌之所以缺乏固定的样式,很大程度上是因为它缺乏清晰的目的。扩展Python时,Python与C之间的职责明确,所以有一个清楚的结构,C类型与模块必须符合标准的扩展结构,来适配Python的类型与模块。这使得Python客户可以无缝集成:C扩展模块就像是Python对象,完成大部份工作。

But when Python is embedded, the structure isn't as obvious; because C is the enclosing level, there is no clear way to know what model the embedded Python code should fit. C may want to run objects fetched from modules, strings fetched from files or parsed out of documents, and so on. Instead of deciding what C can and cannot do, Python provides a collection of general embedding interface tools, which you use and structure according to your embedding goals.

但是当Python内嵌时,结构并不明显;因为C语言是外层,无法知道Python代码应该适配什么样的模型。C要运行的可能是从模块中获取的对象,或者从文件中获取的字符串,或者从文档中解析的字符串,等等。Python没有决定C语言能做什么或不能做什么,而是提供了一系列通用的内嵌接口工具,你要根据自己的目的来使用和组织它们。

Most of these tools correspond to tools available to Python programs. Table 23-1 lists some of the more common API calls used for embedding, as well as their Python equivalents. In general, if you can figure out how to accomplish your embedding goals in pure Python code, you can probably find C API tools that achieve the same results.

这些工具大多数对应Python的语句。表23-1列出了常用的内嵌API,及相对应的Python语句。一般来说,如果你能用纯Python代码完成任务,你就也能用内嵌C API完成任务。

Table 23-1. Common API functions
表23-1. 常用API函数

C API call Python equivalent
PyImport_ImportModule import module, _ _import_ _
PyImport_ReloadModule reload(module)
PyImport_GetModuleDict sys.modules
PyModule_GetDict module._ _dict_ _
PyDict_GetItemString dict[key]
PyDict_SetItemString dict[key]=val
PyDict_New dict = {}
PyObject_GetAttrString getattr(obj, attr)
PyObject_SetAttrString setattr(obj, attr, val)
PyEval_CallObject funcobj(*argstuple), apply
PyRun_String eval(exprstr), exec stmtstr
PyRun_File execfile(filename)

Because embedding relies on API call selection, becoming familiar with the Python C API is fundamental to the embedding task. This chapter presents a handful of representative embedding examples and discusses common API calls, but it does not provide a comprehensive list of all tools in the API. Once you've mastered the examples here, you'll probably need to consult Python's integration manuals for more details on available calls in this domain. As mentioned in the preceding chapter, Python offers two standard manuals for C/C++ integration programmers: Extending and Embedding, an integration tutorial; and Python/C API, the Python runtime library reference.

因为内嵌有赖于API的选择,所以熟悉Python C API是内嵌工作的基本要求。本章举了一些有代表性的内嵌的例子,讨论了常用的API调用,但不是列举完整的API。一旦掌握了这些例子,你可能还需要在Python的帮助手册上查看所有相关API的详细信息。上一章已经提过,Python为C/C++程序员提供了两本帮助手册:集成教程之扩展与内嵌;和Python运行库参考之Python/C API,。

You can find the most recent releases of these manuals at http://www.python.org. Beyond this chapter, these manuals are likely to be your best resource for up-to-date and complete Python API tool information.

可在http://www.python.org找到最新版的帮助手册。除了本章,这两本手册可能是你最新最好最全的Python API工具书。

23.2.1. What Is Embedded Code?
23.2.1. 内嵌代码是什么?

Before we jump into details, let's get a handle on some of the core ideas in the embedding domain. When this book speaks of "embedded" Python code, it simply means any Python program structure that can be executed from C with a direct in-process function call interface. Generally speaking, embedded Python code can take a variety of forms:

进入细节之前,让我们先触及一些内嵌的核心思想。本书所述的“内嵌”Python代码指的是,能在C语言中通过直接的进程内函数调用执行的Python程序。一般说来,内嵌Python代码可以有许多形式:

Code strings
代码串

C programs can represent Python programs as character strings and run them as either expressions or statements (such as eval and exec).

C程序能用字符串表示Python程序,并按表达式或语言运行(如eval和exec)。

Callable objects
可调用对象

C programs can load or reference Python callable objects such as functions, methods, and classes, and call them with argument list objects (such as apply and the newer func(*pargs, *kargs)).

C语序能载入或引用Python可调用对象,如函数,方法,和类,并以参数链表对象为参数调用它们(如apply和新的func(*pargs, **kargs))。

Code files
代码文件

C programs can execute entire Python program files by importing modules and running script files through the API or general system calls (e.g., popen).

C程序能通过API或普通的系统调用(如popen),导入模块并运行脚本文件,来执行整个的Python程序文件。

The Python binary library is usually what is physically embedded in the C program; the actual Python code run from C can come from a wide variety of sources:

Python二进制库通常会内嵌在C程序中;而C语言实际执行的Python代码有多种来源:

Code strings might be loaded from files, obtained from an interactive user, fetched from persistent databases and shelves, parsed out of HTML or XML files, read over sockets, built or hardcoded in a C program, passed to C extension functions from Python registration code, and so on.

代码串可以从文件读取,通过用户交互式获取,从数据库和shelves获取,从HTML或XML文件中解析,从socket读取,构建或硬编码在C程序中,从Python注册代码传递给C扩展函数,等等。

Callable objects might be fetched from Python modules, returned from other Python API calls, passed to C extension functions from Python registration code, and so on.

可调用对象可以从Python模块中获取,从其它Python API调用中返回,从Python注册代码中传递给C扩展函数,等等。

Code files simply exist as files, modules, and executable scripts.

代码文件只是文件,模块,和可执行脚本。

Registration is a technique commonly used in callback scenarios that we will explore in more detail later in this chapter. But especially for strings of code, there are as many possible sources as there are for C character strings. For example, C programs can construct arbitrary Python code dynamically by building and running strings.

注册是回调方式中一个常用的技术,将在本章后面详述。对于代码串来说,可能的来源与C字符串的来源一样多。例如,C程序可以通过构建字符串来动态构造任意的Python代码。

Finally, once you have some Python code to run, you need a way to communicate with it: the Python code may need to use inputs passed in from the C layer and may want to generate outputs to communicate results back to C. In fact, embedding generally becomes interesting only when the embedded code has access to the enclosing C layer. Usually, the form of the embedded code suggests its communication media:

最后,一旦有了要执行的Python代码,你需要一个与之通信的方法:Python可能需要从C语言层输入参数,也可能产生输出结果要返回C。实际上,只有在内嵌代码能够影响外层的C语言时,内嵌才有意义。通常,内嵌代码的形式会暗示出它的通信媒介。

Code strings that are Python expressions return an expression result as their output. Both inputs and outputs can take the form of global variables in the namespace in which a code string is run; C may set variables to serve as input, run Python code, and fetch variables as the code's result. Inputs and outputs can also be passed with exported C extension function callsPython code may use C module or type interfaces that we met in the preceding chapter to get or set variables in the enclosing C layer. Communications schemes are often combined; for instance, C may preassign global names to objects that export state and interface calls to the embedded Python code.[*]

Python表达式代码串的输出是表达式的值。其输入和输出可以是在代码串运行的命名空间的全局变量:C可以设置变量作为输入,运行Python代码,并从变量中获取代码运行的结果。输入和输出也可以通过C扩展函数传递:Python代码可以使用前一章所述的C模块或类型的接口,来读写外部C语言层的变量。通信方式常常是混合的:例如,C可以预设一些全局对象,这些对象输出状态和接口给内嵌的Python代码。[*]

[*] If you want a concrete example, flip back to the discussion of Active Scripting in Chapter 18. This system fetches Python code embedded in an HTML web page file, assigns global variables in a namespace to objects that give access to the web browser's environment, and runs the Python code in the namespace where the objects were assigned. I worked on a project where we did something similar, but Python code was embedded in XML documents, and objects that were preassigned to globals in the code's namespace represented widgets in a GUI.

[*] 如果你想要一个具体的例子,翻到前面18章中Active Scripting的讨论。那个系统提取HTML网页文件中的内嵌Python代码,将一些全局变量赋值为对象,通过这些对象来操作浏览器环境,并在这些对象的命名空间中运行Python代码。我工作的一个项目也是这样,只是Python代码内嵌在XML文档中,而预设的全局对象是GUI部件。

Callable objects may accept inputs as function arguments and produce results as function return values. Passed-in mutable arguments (e.g., lists, dictionaries, class instances) can be used as both input and output for the embedded codechanges made in Python are retained in objects held by C. Objects can also make use of the global variable and C extension functions interface techniques described for strings to communicate with C.

可调用对象可以像函数一样接受输入参数,并产生函数返回值作为输出。传入的可变参数,例如链表,字典,类实例,可同时作为输入和输出,因为在Python内嵌代码中的更改是保持在C语言的对象中的。和Python代码串一样,对象也可以使用全局变量和C扩展函数接口来与C通信。

Code files can communicate with most of the same techniques as code strings; when run as separate programs, files can also employ Inter-Process Communication (IPC) techniques.

代码文件可以使用与代码串几乎同样的技术来通信;当作为独立的程序运行时,代码文件还可以使用进程间通信(IPC)技术。

Naturally, all embedded code forms can also communicate with C using general system-level tools: files, sockets, pipes, and so on. These techniques are generally less direct and slower, though. Here, we are still interested in in-process function call integration.

当然,内嵌代码的所有形式还可以使用通常的系统工具来与C通信:文件,套接字,管道,等等。但是这些技术一般不是直接的并且较慢。这里,我们感兴趣的仍然是进程内的函数调用级的集成。

1. 评译

Name Password4deL ;) :( X-( B-)
fepoj ogskez   qjrc itklvpwh qywzip eltgrhvcq lomfakwd qsyd ectaf
2007-11-13 13:00:50