[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

There is one subtlety in this embedding mode: dictionaries that serve as namespaces
for running code are generally required to have a builtins link to the built-in scope
searched last for name lookups, set with code of this form:


PyDict_SetItemString(pdict, "__builtins__", PyEval_GetBuiltins());

This is esoteric, and it is normally handled by Python internally for modules and built-
ins like the exec function. For raw dictionaries used as namespaces, though, we are
responsible for setting the link manually if we expect to reference built-in names. This
still holds true in Python 3.X.


Precompiling Strings to Bytecode


Finally, when you call Python function objects from C, you are actually running the
already compiled bytecode associated with the object (e.g., a function body), normally
created when the enclosing module is imported. When running strings, Python must
compile the string before running it. Because compilation is a slow process, this can be
a substantial overhead if you run a code string more than once. Instead, precompile
the string to a bytecode object to be run later, using the API calls illustrated in
Example 20-29:


Py_CompileString
Compiles a string of code and returns a bytecode object


PyEval_EvalCode
Runs a compiled bytecode object


The first of these takes the mode flag that is normally passed to PyRun_String, as well
as a second string argument that is used only in error messages. The second takes two
namespace dictionaries. These two API calls are used in Example 20-29 to compile and
execute three strings of Python code in turn.


Example 20-29. PP4E\Integrate\Embed\Basics\embed-bytecode.c


/ precompile code strings to bytecode objects /


#include <Python.h>
#include <compile.h>
#include <eval.h>


main() {
int i;
char cval;
PyObject
pcode1, pcode2, pcode3, presult, pdict;
char codestr1, codestr2, *codestr3;
printf("embed-bytecode\n");


Py_Initialize();
codestr1 = "import usermod\nprint(usermod.message)"; / statements /
codestr2 = "usermod.transform(usermod.message)"; / expression /
codestr3 = "print('%d:%d' % (X, X * 2), end=' ')"; / use input X */


1528 | Chapter 20: Python/C Integration

Free download pdf