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

(yzsuai) #1

//
/
3) module definition /
/
/


static struct PyModuleDef cenvironmodule = {
PyModuleDef_HEAD_INIT,
"cenviron", / name of module /
"cenviron doc", / module documentation, may be NULL /
−1, / size of per-interpreter module state, −1=in global vars /
cenviron_methods / link to methods table /
};


//
/
4) module initializer /
/
/


PyMODINIT_FUNC
PyInit_cenviron() / called on first import /
{ / name matters if loaded dynamically /
return PyModule_Create(&cenvironmodule);
}


Though demonstrative, this example is arguably less useful now than it was in the first
edition of this book—as we learned in Part II, not only can you fetch shell environment
variables by indexing the os.environ table, but assigning to a key in this table auto-
matically calls C’s putenv to export the new setting to the C code layer in the process.
That is, os.environ['key'] fetches the value of the shell variable 'key', and
os.environ['key']=value assigns a variable both in Python and in C.


The second action—pushing assignments out to C—was added to Python releases after
the first edition of this book was published. Besides illustrating additional extension
coding techniques, though, this example still serves a practical purpose: even today,
changes made to shell variables by the C code linked into a Python process are not
picked up when you index os.environ in Python code. That is, once your program
starts, os.environ reflects only subsequent changes made by Python code in the process.


Moreover, although Python now has both a putenv and a getenv call in its os module,
their integration seems incomplete. Changes to os.environ call os.putenv, but direct
calls to os.putenv do not update os.environ, so the two can become out of sync. And
os.getenv today simply translates to an os.environ fetch, and hence will not pick up
environment changes made in the process outside of Python code after startup time.
This may rarely, if ever, be an issue for you, but this C extension module is not com-
pletely without purpose; to truly interface environment variables with linked-in C code,
we need to call the C library routines directly (at least until Python changes this
model again!).


The cenviron.c C file in Example 20-8 creates a Python module called cenviron that
does a bit more than the prior examples—it exports two functions, sets some exception
descriptions explicitly, and makes a reference count call for the Python None object (it’s
not created anew, so we need to add a reference before passing it to Python). As before,


Wrapping C Environment Calls | 1497
Free download pdf