__next__ 和 __str__ 是否由等效的 next 和 str 函数在内部调用?
Are __next__ and __str__ invoked by the equivalent next and str functions internally?
来自 Learning python 书第 5 版:
Page 421, footnote2:
Technically speaking, the for
loop calls the internal equivalent of I.__next__
, instead of the next(I)
used here, though there is rarely any difference between the two. Your manual iterations can generally use either call scheme.
这到底是什么意思?这是否意味着 I.__next__
由 C 函数调用,而不是 for
循环或任何内置迭代上下文中的 str
内置函数?
Page 914:
__str__
is tried first for the print
operation and the str
built-in function (the internal equivalent of which print
runs). It generally should return a user-friendly display.
除了书本之外,Python 是否像我从书中理解的那样在内部使用 C 函数调用 __str__
或 __next__
?
Python C 实现使用的 C 函数 本质上 与 Python 函数相同,因为 Python 函数类似于str()
和 next()
通常是 C 函数的薄包装。
然后这些 C 函数负责调用正确的钩子;这可能是钩子的 C 版本(结构中指向函数的槽),或 class.
上的 Python 函数
现在,str()
和 next()
在这里都比包装器多一点,因为这些函数定义了额外的功能,需要更多的实现工作;例如,next()
采用定义默认值的第二个参数。
所以我将以len()
为例。该函数定义在 builtin_len()
C function:
static PyObject *
builtin_len(PyObject *self, PyObject *v)
{
Py_ssize_t res;
res = PyObject_Size(v);
if (res < 0 && PyErr_Occurred())
return NULL;
return PyInt_FromSsize_t(res);
}
注意调用PyObject_Size()
;这就是 C 代码用来获取对象长度的方法。剩下的只是错误处理和生成 Python int
对象。
PyObject_Size()
那么就是 implemented like this:
Py_ssize_t
PyObject_Size(PyObject *o)
{
PySequenceMethods *m;
if (o == NULL) {
null_error();
return -1;
}
m = o->ob_type->tp_as_sequence;
if (m && m->sq_length)
return m->sq_length(o);
return PyMapping_Size(o);
}
它接受一个PyObject
结构,从那里找到ob_type
结构,它有一个可选的tp_as_sequence
结构,它可以定义一个sq_length
函数指针。如果存在,则调用它来产生实际长度。不同的类型可以定义该函数,并且 Python 实例的特殊 C 结构可以处理重定向回 Python 方法。
所有这些都表明 Python 的内部实现使用了大量抽象来实现对象,允许 C 定义的类型和 Python classes 被同等对待, 大多数情况下。如果您想深入挖掘,Python 文档有 full coverage of the C-API, including a dedicated tutorial.
回到原来的两个函数,next()
的内部等价物是 PyIter_Next()
, and str()
, as used for string conversions of arbitrary objects, is PyObject_Str()
。
来自 Learning python 书第 5 版:
Page 421, footnote2:
Technically speaking, the
for
loop calls the internal equivalent ofI.__next__
, instead of thenext(I)
used here, though there is rarely any difference between the two. Your manual iterations can generally use either call scheme.
这到底是什么意思?这是否意味着 I.__next__
由 C 函数调用,而不是 for
循环或任何内置迭代上下文中的 str
内置函数?
Page 914:
__str__
is tried first for thestr
built-in function (the internal equivalent of which
除了书本之外,Python 是否像我从书中理解的那样在内部使用 C 函数调用 __str__
或 __next__
?
Python C 实现使用的 C 函数 本质上 与 Python 函数相同,因为 Python 函数类似于str()
和 next()
通常是 C 函数的薄包装。
然后这些 C 函数负责调用正确的钩子;这可能是钩子的 C 版本(结构中指向函数的槽),或 class.
上的 Python 函数现在,str()
和 next()
在这里都比包装器多一点,因为这些函数定义了额外的功能,需要更多的实现工作;例如,next()
采用定义默认值的第二个参数。
所以我将以len()
为例。该函数定义在 builtin_len()
C function:
static PyObject *
builtin_len(PyObject *self, PyObject *v)
{
Py_ssize_t res;
res = PyObject_Size(v);
if (res < 0 && PyErr_Occurred())
return NULL;
return PyInt_FromSsize_t(res);
}
注意调用PyObject_Size()
;这就是 C 代码用来获取对象长度的方法。剩下的只是错误处理和生成 Python int
对象。
PyObject_Size()
那么就是 implemented like this:
Py_ssize_t
PyObject_Size(PyObject *o)
{
PySequenceMethods *m;
if (o == NULL) {
null_error();
return -1;
}
m = o->ob_type->tp_as_sequence;
if (m && m->sq_length)
return m->sq_length(o);
return PyMapping_Size(o);
}
它接受一个PyObject
结构,从那里找到ob_type
结构,它有一个可选的tp_as_sequence
结构,它可以定义一个sq_length
函数指针。如果存在,则调用它来产生实际长度。不同的类型可以定义该函数,并且 Python 实例的特殊 C 结构可以处理重定向回 Python 方法。
所有这些都表明 Python 的内部实现使用了大量抽象来实现对象,允许 C 定义的类型和 Python classes 被同等对待, 大多数情况下。如果您想深入挖掘,Python 文档有 full coverage of the C-API, including a dedicated tutorial.
回到原来的两个函数,next()
的内部等价物是 PyIter_Next()
, and str()
, as used for string conversions of arbitrary objects, is PyObject_Str()
。