|
5 | 5 | ----------
|
6 | 6 | 问题
|
7 | 7 | ----------
|
8 |
| -You want to write C extension code that consumes items from any iterable object such |
9 |
| -as a list, tuple, file, or generator. |
| 8 | +你想写C扩展代码处理来自任何可迭代对象如列表、元组、文件或生成器中的元素。 |
10 | 9 |
|
11 | 10 | |
|
12 | 11 |
|
13 | 12 | ----------
|
14 | 13 | 解决方案
|
15 | 14 | ----------
|
16 |
| -Here is a sample C extension function that shows how to consume the items on an |
17 |
| -iterable: |
18 |
| - |
19 |
| -static PyObject *py_consume_iterable(PyObject *self, PyObject *args) { |
20 |
| - PyObject *obj; |
21 |
| - PyObject *iter; |
22 |
| - PyObject *item; |
23 |
| -
|
24 |
| - if (!PyArg_ParseTuple(args, "O", &obj)) { |
25 |
| - return NULL; |
26 |
| - } |
27 |
| - if ((iter = PyObject_GetIter(obj)) == NULL) { |
28 |
| - return NULL; |
29 |
| - } |
30 |
| - while ((item = PyIter_Next(iter)) != NULL) { |
31 |
| - /* Use item */ |
32 |
| - ... |
33 |
| - Py_DECREF(item); |
34 |
| - } |
35 |
| -
|
36 |
| - Py_DECREF(iter); |
37 |
| - return Py_BuildValue(""); |
38 |
| -} |
| 15 | +下面是一个C扩展函数例子,演示了怎样处理可迭代对象中的元素: |
| 16 | + |
| 17 | +:: |
| 18 | + |
| 19 | + static PyObject *py_consume_iterable(PyObject *self, PyObject *args) { |
| 20 | + PyObject *obj; |
| 21 | + PyObject *iter; |
| 22 | + PyObject *item; |
| 23 | + |
| 24 | + if (!PyArg_ParseTuple(args, "O", &obj)) { |
| 25 | + return NULL; |
| 26 | + } |
| 27 | + if ((iter = PyObject_GetIter(obj)) == NULL) { |
| 28 | + return NULL; |
| 29 | + } |
| 30 | + while ((item = PyIter_Next(iter)) != NULL) { |
| 31 | + /* Use item */ |
| 32 | + ... |
| 33 | + Py_DECREF(item); |
| 34 | + } |
| 35 | + |
| 36 | + Py_DECREF(iter); |
| 37 | + return Py_BuildValue(""); |
| 38 | + } |
39 | 39 |
|
40 | 40 | |
|
41 | 41 |
|
42 | 42 | ----------
|
43 | 43 | 讨论
|
44 | 44 | ----------
|
45 |
| -The code in this recipe mirrors similar code in Python. The PyObject_GetIter() call |
46 |
| -is the same as calling iter() to get an iterator. The PyIter_Next() function invokes |
47 |
| -the next method on the iterator returning the next item or NULL if there are no more |
48 |
| -items. Make sure you’re careful with memory management—Py_DECREF() needs to be |
49 |
| -called on both the produced items and the iterator object itself to avoid leaking memory. |
| 45 | +本节中的代码和Python中对应代码类似。 |
| 46 | +``PyObject_GetIter()`` 的调用和调用 ``iter()`` 一样可获得一个迭代器。 |
| 47 | +``PyIter_Next()`` 函数调用 ``next`` 方法返回下一个元素或NULL(如果没有元素了)。 |
| 48 | +要注意正确的内存管理—— ``Py_DECREF()`` 需要同时在产生的元素和迭代器对象本身上同时被调用, |
| 49 | +以避免出现内存泄露。 |
0 commit comments