`
DYER
  • 浏览: 50460 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Extending and Embedding the Python Interpreter(二)

阅读更多

An important convention throughout the Python interpreter is the following: when a function fails, it should set an exception condition and return an error value (usually a NULL pointer). Exceptions are stored in a static global variable inside the interpreter; if this variable is NULL no exception has occurred. A second global variable stores the ``associated value'' of the exception (the second argument to raise). A third variable contains the stack traceback in case the error originated in Python code. These three variables are the C equivalents of the Python variables sys.exc_type, sys.exc_value and sys.exc_traceback (see the section on module sys in the Python Library Reference). It is important to know about them to understand how errors are passed around.

在python解释器里有很重要的一点是当一个函数发生错误时,它需要发出异常信息并且返回一个错误值。异常被存储在解释器的一个静态全局变量中,如果这个变量为NULL,那么就代表没有异常发生。第二个全局变量存储了与异常相关的信息。第三个变量存储了堆栈中的关于异常在源代码中的信息。这三个变量等效与python中的sys.exc_type, sys.exc_value and sys.exc_traceback 三个变量。

The Python API defines a number of functions to set various types of exceptions.

python api定义了一些设置异常类别的函数

The most common one is PyErr_SetString(). Its arguments are an exception object and a C string. The exception object is usually a predefined object like PyExc_ZeroDivisionError. The C string indicates the cause of the error and is converted to a Python string object and stored as the ``associated value'' of the exception.

PyErr_SetString()函数有两个参数,一个是异常对象,一个是C的字符串。此处的异常对象通常是预设的,而字符串用来说明产生异常的原因并且被转换为python字符串对象并存储在第二个全局变量中。

Another useful function is PyErr_SetFromErrno(), which only takes an exception argument and constructs the associated value by inspection of the global variable errno. The most general function is PyErr_SetObject(), which takes two object arguments, the exception and its associated value. You don't need to Py_INCREF() the objects passed to any of these functions.

另一个比较有用的函数是PyErr_SetFromErrno(),它只有一个参数,代表异常;通过检查全局便来那个errno来创建异常相关信息的值。最常用的函数是PyErr_SetObject(),它有两个参数,一个是异常对象另一个是与异常相关的信息。在使用这些函数时,不需要使用Py_INCREF()来维护这些异常对象的计数。

You can test non-destructively whether an exception has been set with PyErr_Occurred(). This returns the current exception object, or NULL if no exception has occurred. You normally don't need to call PyErr_Occurred() to see whether an error occurred in a function call, since you should be able to tell from the return value.

可以通过使用函数PyErr_Occurred()来测试是否有异常发生,发生时返回异常对象,如果返回NULL则代表没有异常发生。

When a function f that calls another function g detects that the latter fails, f should itself return an error value (usually NULL or -1). It should not call one of the PyErr_*() functions -- one has already been called by g. f's caller is then supposed to also return an error indication to its caller, again without calling PyErr_*(), and so on -- the most detailed cause of the error was already reported by the function that first detected it. Once the error reaches the Python interpreter's main loop, this aborts the currently executing Python code and tries to find an exception handler specified by the Python programmer.

如果一个函数f调用另一个函数g,并且函数g在执行中发生了错误,那么f需要返回一个错误值,通常为NULL或是-1。此处不能再去调用形如PyErr_*() 的函数,因为它们已经在函数g中被调用了。以此类推,调用f的函数也一样不能调用形如PyErr_*() 的函数。

To ignore an exception set by a function call that failed, the exception condition must be cleared explicitly by calling PyErr_Clear(). The only time C code should call PyErr_Clear() is if it doesn't want to pass the error on to the interpreter but wants to handle it completely by itself (possibly by trying something else, or pretending nothing went wrong).

如果需要忽略在调用一个函数时发生的错误,那么需要显式的调用PyErr_Clear(),在C代码中调用该函数的唯一理由就是不希望将该错误传入解释器而希望自己在C代码中处理。

Every failing malloc() call must be turned into an exception -- the direct caller of malloc() (or realloc()) must call PyErr_NoMemory() and return a failure indicator itself. All the object-creating functions (for example, PyInt_FromLong()) already do this, so this note is only relevant to those who call malloc() directly.

每一次直接调用malloc函数如果发生错误的话都要引发一个异常,调用PyErr_NoMemory()并且返回一个错误引用。其它创建的对象已经在内部这样做了所以不需要手工添加这个步骤。

Also note that, with the important exception of PyArg_ParseTuple() and friends, functions that return an integer status usually return a positive value or zero for success and -1 for failure, like Unix system calls.

当返回一个整数值表示状态时,通常返回一个正数或者0表示成功,返回-1表示失败

Finally, be careful to clean up garbage (by making Py_XDECREF() or Py_DECREF() calls for objects you have already created) when you return an error indicator!

The choice of which exception to raise is entirely yours. There are predeclared C objects corresponding to all built-in Python exceptions, such as PyExc_ZeroDivisionError, which you can use directly. Of course, you should choose exceptions wisely -- don't use PyExc_TypeError to mean that a file couldn't be opened (that should probably be PyExc_IOError). If something's wrong with the argument list, the PyArg_ParseTuple() function usually raises PyExc_TypeError. If you have an argument whose value must be in a particular range or must satisfy other conditions, PyExc_ValueError is appropriate.

返回什么样的异常完全取决于你,已经存在了许多声明好的C语言对象来对应所有的python异常。

You can also define a new exception that is unique to your module. For this, you usually declare a static object variable at the beginning of your file:

你也可以自己定义新的异常,如果要那样做的话,你需要在你源文件的开头进行如下的声明:

 

static PyObject *SpamError;

and initialize it in your module's initialization function (initspam()) with an exception object (leaving out the error checking for now):

并且在你的初始化函数中对这个异常进行初始化

 

PyMODINIT_FUNC
initspam(void)
{
    PyObject *m;

    m = Py_InitModule("spam", SpamMethods);

    SpamError = PyErr_NewException("spam.error", NULL, NULL);
    Py_INCREF(SpamError);
    PyModule_AddObject(m, "error", SpamError);
}

Note that the Python name for the exception object is spam.error. The PyErr_NewException()

function may create a class with the base class being Exception (unless another class is

passed in instead of NULL), described in the Python Library Reference under ``Built-in

Exceptions.

 

注意此处该异常被命名为spam.error。 PyErr_NewException()函数以Exception为基类创建新的异常类,如果要

指定其它基类,需要用基类的名字代替NULL。

 

Note also that the SpamError variable retains a reference to the newly created exception

class; this is intentional! Since the exception could be removed from the module by external

code, an owned reference to the class is needed to ensure that it will not be discarded,

causing SpamError to become a dangling pointer. Should it become a dangling pointer, C code

which raises the exception could cause a core dump or other unintended side effects.

 

同时注意SpamError变量保留了一个对新创建的异常对象的引用,它是内部的。因为外部代码可以从模块中移除异常,所以

保留一个对该异常对象的引用可以保证该对象不被丢弃。

分享到:
评论

相关推荐

    Python-3-0-1

    It is a companion to Extending and Embedding the Python Interpreter (in Extending and Embedding Python), which describes the general principles of extension writing but does not document the API ...

    Python 2.71 Document

    Welcome! This is the ...Extending and embedding the python interpreter Python /C API reference Manual Installing python modules Documenting Python Python HOWTOs Python Frequently Asked questions

    Python库参考手册.pdf

    Finally, the manual entitled Extending and Embedding the Python Interpreter describes how to add new extensions to Python and how to embed it in other applications. 本手册的读者要对Python 有基本的...

    Python in a Nutshell. A Desktop Quick Reference

    The book focuses on Python’s cross-platform capabilities and covers the basics of extending Python and embedding it in other applications. How This Book Is Organized This book has five parts, as ...

    Python参考手册

    Finally, the manual entitled Extending and Embedding the Python Interpreter describes how to add new extensions to Python and how to embed it in other applications. 本手册的读者要对Python 有基本的认识...

    Python教程(原文).doc

    而关于使用C或C++扩展Python功能,建议阅读《Extending and Embedding the Python Interpreter》和《Python/C API Reference》。 Python不仅适合处理大型项目,提供比shell脚本更强的结构和错误检查,而且它的高阶...

    Python教程(原文).pdf

    对于使用C或C++扩展Python功能,"Extending and Embedding the Python Interpreter"和"Python/C API Reference"是重要的参考资料。 教程中的“开胃菜”部分指出,Python特别适合那些需要在shell脚本的基础上增加...

    python-tutorial.pdf

    如果你计划用C或C++来扩展Python,需要阅读《Extending and Embedding the Python Interpreter》以及《Python/C API Reference》。此外,市面上还有许多专门涵盖Python编程的书籍,这些资源能够进一步提升你的技能和...

    Python 2[1].5 Documentation (19 September 20 06)

    3. **Extending and Embedding the Python Interpreter**:这部分内容主要针对想要在Python之外的环境中使用Python或扩展Python功能的开发者。它讲解了如何用C或C++编写Python扩展模块,以及如何在其他应用程序中...

    Tutorial Python

    对于希望使用C或C++扩展Python解释器的开发者,《Extending and Embedding the Python Interpreter》与《Python/C API Reference》是必读之选。这两份文档详细介绍了如何利用C语言增强Python的功能,以及如何将...

    python3.6.5参考手册 chm

    PEP 486: Make the Python Launcher aware of virtual environments PEP 488: Elimination of PYO files PEP 489: Multi-phase extension module initialization Other Language Changes New Modules typing ...

    Mayavi 参考

    The embedded Python interpreter Recording Mayavi actions to a script Command line arguments mlab: Python scripting for 3D plotting A demo 3D Plotting functions for numpy arrays 0D and 1D data 2D ...

Global site tag (gtag.js) - Google Analytics