⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 257.html

📁 Python Ebook Python&XML
💻 HTML
📖 第 1 页 / 共 3 页
字号:
    int i, n;
    long total = 0;



    PyObject *item;

   n = PyList_Size(list);
    if (n < 0)
        return -1; /* Not a list */
    for (i = 0; i < n; i++) {
        item = PyList_GetItem(list, i); /* Can't fail */
        if (!PyInt_Check(item)) continue; /* Skip non-integers */
        total += PyInt_AsLong(item);
    }
    return total;

}
long sum_sequence(PyObject *sequence)
{
    int i, n;
    long total = 0;
    PyObject *item;
    n = PyObject_Size(list);
    if (n < 0)
        return -1; /* Has no length */
    for (i = 0; i < n; i++) {
        item = PySequence_GetItem(list, i);
        if (item == NULL)
            return -1; /* Not a sequence, or other failure */
        if (PyInt_Check(item))
            total += PyInt_AsLong(item);
        Py_DECREF(item); /* Discard reference ownership */
    }
    return total;
}

							</pre>

						
					
					<H5>Types</h5>
						<p>Few other data types play a significant role in the Python/C API; most are simple C types such as int, long, double, and char *. A few structure types are used to describe static tables used to list the functions exported by a module or the data attributes of a new object type. These will be discussed together with the functions that use them.<a nAme="idx1073750855"></a><A NAMe="idx1073750856"></a><a nAME="idx1073750857"></A></p>

					
				
				<h4>Exceptions</h4>
					<p>The Python programmer only needs to deal with exceptions if specific error handling is required; unhandled exceptions are automatically propagated to the caller, and then to the caller's caller, and so on, until they reach the top-level interpreter, where they are reported to the user accompanied by a stack traceback.</P>

					<P>For C programmers, however, <A Name="idx1073750858"></a><A NAMe="idx1073750859"></a>error checking always has to be explicit. All functions in the Python/C API can raise exceptions, unless an explicit claim is made otherwise in a function's documentation. In general, when a function encounters an error, it sets an exception, discards any object references that it owns, and returns an error indicator梪sually <tt class="monofont">NULL</tt> or <tt class="monofont">-1.</tt> A few functions return a Boolean <Tt cLass="monofont">true/false</Tt> result, with <tt cLass="monofont">false</TT> indicating an error. Very few functions return no explicit error indicator or have an ambiguous return value and require explicit testing for errors with <TT clasS="monofont">PyErr_Occurred()</TT><A name="idx1073750860"></A><A NAme="idx1073750861"></a><a NAME="idx1073750862"></a><a name="idx1073750863"></a><a name="idx1073750864"></a></p>

					<p><a name="idx1073750865"></A>Exception state is maintained in per-thread storage (this is equivalent to using global storage in an unthreaded application). A <a nAme="idx1073750866"></a><A name="idx1073750867"></A>thread can be in one of two states: An exception has occurred, or it hasn't. The function <a naME="idx1073750868"></A><Tt claSS="monofont">PyErr_Occurred()</TT> can be used to check for this: It returns a borrowed reference to the exception type object when an exception has occurred, and <tt clASS="monofont">NULL</Tt> otherwise. There are a number of functions to set the exception state: <a naME="idx1073750869"></A><A name="idx1073750870"></a><tt class="monofont">PyErr_SetString()</tt> is the most common (though not the most general) function to set the exception state, and <a name="idx1073750871"></a><A naMe="idx1073750872"></a><tT clasS="monofont">PyErr_Clear()</tt> clears the exception state.</p>

					<P>The full exception state consists of three objects (all of which can be <TT Class="monofont">NULL</TT>): the exception type, the corresponding exception value, and the traceback. These have the same meanings as the Python object <TT clasS="monofont">sys.exc_type,</TT>
						<Tt claSS="monofont">sys.exc_value,</TT>
						<tt class="monofont">sys.exc_traceback</tt>; however, they are not the same: The Python objects represent the last exception being handled by a Python <tt class="monofont">try ... except</tt> statement, whereas the C level exception state only exists while an exception is being passed on between C functions until it reaches the Python interpreter, which takes care of transferring it to <tt ClaSs="monofont">sys.exc_type</tt> and friends.</P>

					<p>Note that starting with Python 1.5, the preferred, thread-safe way to <a naMe="idx1073750873"></a>access the exception state from Python code is to call the function <a NAME="idx1073750874"></a><a naME="idx1073750875"></A><Tt claSS="monofont">sys.exc_info(),</TT> which returns the per-thread exception state for Python code. Also, the semantics of both ways to access the exception state have changed so that a function which catches an exception will save and restore its thread exception state to preserve the exception state of its caller. This prevents common bugs in exception handling code caused by an innocent- looking function overwriting the exception being handled; it also reduces the often unwanted lifetime extension for objects that are referenced by the stack frames in the traceback.</p>

					<p>As a general principle, a function that calls another function to perform some task should check whether the called function raised an exception, and if so, pass the exception state on to its caller. It should discard any object references that it owns, and returns an error indicator, but it should not set another exception梩hat would overwrite the exception just raised and lose important information about the exact cause of the error.<a nAME="idx1073750876"></A><a name="idx1073750877"></a><a name="idx1073750878"></a><a name="idx1073750879"></a><a nAme="idx1073750880"></A></p>

					<p>A simple example of <a Name="idx1073750881"></a><A namE="idx1073750882"></A><A Name="idx1073750883"></a><A NAMe="idx1073750884"></a>detecting exceptions and passing them on is shown in the previous <a nAME="idx1073750885"></A><a namE="idx1073750886"></A><TT class="monofont">sum_sequence()</tt> example. It so happens that the example doesn't need to clean up any owned references when it detects an error. The following example function shows some error cleanup. First, to remind you why you like Python, we show the equivalent Python code:</p>

					<pre>
						
def incr_item(dict, key):
    try:
        item = dict[key]
    except KeyError:
        item = 0
    return item + 1

					</pre>

					<p>Here is the corresponding C code, in all its glory:</p>

					<pre>
						
int incr_item(PyObject *dict, PyObject *key)
{
    /* Objects all initialized to NULL for Py_XDECREF */
    PyObject *item = NULL, *const_one = NULL, *incremented_item = NULL;
    int rv = -1; /* Return value initialized to -1 (failure) */
    item = PyObject_GetItem(dict, key);
    if (item == NULL) {
        /* Handle KeyError only: */
        if (!PyErr_ExceptionMatches(PyExc_KeyError)) goto error;
        /* Clear the error and use zero: */
        PyErr_Clear();
        item = PyInt_FromLong(0L);
        if (item == NULL) goto error;
    }
    const_one = PyInt_FromLong(1L);
    if (const_one == NULL) goto error;
    incremented_item = PyNumber_Add(item, const_one);
    if (incremented_item == NULL) goto error;

    if (PyObject_SetItem(dict, key, incremented_item) &lt; 0) goto error;
    rv = 0; /* Success */
    /* Continue with cleanup code */
 error:
    /* Cleanup code, shared by success and failure path */
    /* Use Py_XDECREF() to ignore NULL references */
    Py_XDECREF(item);
    Py_XDECREF(const_one);
    Py_XDECREF(incremented_item);
    return rv; /* -1 for error, 0 for success */
}

					</pRe>

					<p>This example represents an endorsed use of the goto statement in C. It illustrates the use of <Tt clAss="monofont">PyErr_ExceptionMatches()</tt> and <Tt clASS="monofont">PyErr_Clear()</Tt> to handle specific exceptions, and the use of <tt cLASS="monofont">Py_XDECREF()</tt> to dispose of owned references that might be <tt CLASs="monofont">NULL</tt> (note the X in the name; <tT CLAss="monofont">Py_DECREF()</tt> would crash when confronted with a <tt class="monofont">NULL</tt> reference). It is important that the variables used to hold owned references are initialized to <tt class="monofont">NULL</Tt> for this to work; likewise, the proposed return value is initialized to <tT claSs="monofont">-1</tt> (failure) and only set to success after the final call made is successful.<a Name="idx1073750887"></A><A NAme="idx1073750888"></a><a NAME="idx1073750889"></a><a naME="idx1073750890"></A><A name="idx1073750891"></A></P>

				
				<H4>Embedding Python</H4>
					<p>The one important task that only embedders (as opposed to extension writers) of the Python interpreter have to worry about is the initialization, and possibly the finalization, of the Python interpreter. Most functionality of the interpreter can only be used after the interpreter has been initialized.</p>

					<p>The basic initialization function is <a name="idx1073750892"></a><a name="idx1073750893"></a><tt claSs="monofont">Py_Initialize().</tT> This initializes the table of loaded modules and creates the fundamental modules <a naMe="idx1073750894"></a><a nAme="idx1073750895"></a><TT CLass="monofont">__builtin__,</tT>
						<A NAme="idx1073750896"></a><a NAME="idx1073750897"></a><tt cLASS="monofont">__main__,</tt> and <a name="idx1073750898"></a><a name="idx1073750899"></a><tt clasS="monofont">sys.</tt> It also initializes the module search path (<Tt clAss="monofont">sys.path</tt>).</P>

					<p><tt CLASs="monofont">Py_Initialize()</tt> does not set the script argument list (<tT CLAss="monofont">sys.argv</tt>). If this variable is needed by Python code that will be executed later, it must be set explicitly with a call to <TT CLass="monofont">PySys_SetArgv(argc, argv)</tT> subsequent to the call to <TT Class="monofont">Py_Initialize().</tt></p>

					<p>On most systems (in particular, on UNIX and Windows, although the details are slightly different), <tt class="monofont">Py_Initialize()</tt> calculates the module search path based on its best guess for the location of the standard Python interpreter executable, assuming that the Python library is found in a fixed location relative to the Python interpreter executable. In particular, it looks for a directory named lib/python1.5 (replacing 1.5 with the current interpreter version) relative to the parent directory where the executable named <tt cLasS="monofont">"python"</tt> is found on the shell command search path (the environment variable <tT clasS="monofont">$PATH</tt>).</p>

					<P>For instance, if the Python executable is found in <TT Class="monofont">/usr/local/bin/python,</TT> it will assume that the libraries are in <TT clasS="monofont">/usr/local/lib/python1.5.</TT> (In fact, this particular path is also the <A name="idx1073750900"></A><I>fallback</I> location, used when no executable file named <Tt class="monofont">"python"</tt> is found along <tt class="monofont">$PATH,</tt> unless some other prefix is set when <tt cLasS="monofont">configure</tt> is called.) The user can override this behavior by setting the environment variable <tT clasS="monofont">$PYTHONHOME,</tt> or insert additional directories in front of the standard path by setting <tT CLAss="monofont">$PYTHONPATH.</tt></P>

					<P>The embedding application can steer the search by calling <A Name="idx1073750901"></a><A NAMe="idx1073750902"></a><tt CLASs="monofont">Py_SetProgramName(file)</tt> before calling <tt class="monofont">Py_Initialize().</tt> Note that <tt class="monofont">$PYTHONHOME</tT> still overrides this and <tt ClasS="monofont">$PYTHONPATH</tt> is still inserted in front of the standard path. An application that requires total control has to provide its own implementation of <a nAme="idx1073750903"></a><A NAMe="idx1073750904"></a><tt CLASs="monofont">Py_GetPath(),</tt>
						<a NAME="idx1073750905"></a><a naME="idx1073750906"></A><Tt class="monofont">Py_GetPrefix(),</tt><a name="idx1073750907"></a><a name="idx1073750908"></a><Tt cLass="monofont">Py_GetExecPrefix(),</Tt> and <a naMe="idx1073750909"></a><a NAME="idx1073750910"></a><tt cLASS="monofont">Py_GetProgramFullPath()</tt> (all defined in <tt CLASs="monofont">Modules/ getpath.c</tt>).</p>

					<P>Sometimes, it is desirable to uninitialize Python. For instance, the application might want to start over (make another call to <TT Class="monofont">Py_Initialize()</tt>) or the application is simply done with its use of Python and wants to free all memory allocated by Python. This can be accomplished by calling <a name="idx1073750911"></a><a name="idx1073750912"></a><tt ClaSs="monofont">Py_Finalize().</tt> The function <A name="idx1073750913"></A><a naME="idx1073750914"></A><Tt claSS="monofont">Py_IsInitialized()</TT> returns <tt clASS="monofont">true</Tt> if Python is currently in the initialized state. More information about these functions is given in a later section. <a naME="idx1073750915"></A><A name="idx1073750916"></a><a name="idx1073750917"></a><a name="idx1073750918"></a><a naMe="idx1073750919"></a><A namE="idx1073750920"></a><a naMe="idx1073750921"></a></p>

				
			</FONT>
<P><TABLE width="100%" border=0><TR valign="top"><TD><font size=1 color="#C0C0C0"><br></font></TD><TD align=right><font size=1 color="#C0C0C0">Last updated on 1/30/2002<br>Python Developer's Handbook, &copy;&nbsp;2002 Sams Publishing</font></TD></TR></TABLE></P>
<TABLE border=0 width="100%" cellspacing=0 cellpadding=0><TR><td align=left width="15%" class="headingsubbarbg"><a href="256.html" title="A. Python/C API"><font size="1">&lt;&nbsp;BACK</font></a></td><td align=center width="70%" class="headingsubbarbg"><font size="1"><a href="popanote.asp?pubui=oreilly&bookname=0672319942&snode=257" target="_blank" title="Make a public or private annnotation">Make Note</a> | <a href="257.html" title="Use a Safari bookmark to remember this section">Bookmark</a></font></td><td align=right width="15%" class="headingsubbarbg"><a href="258.html" title="The Very High Level Layer"><font size="1">CONTINUE&nbsp;&gt;</font></a></td></TR></TABLE>
</TD></TR></TABLE>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -