__next__和__str__是否由内部等效的next和str函数调用?

时间:2016-04-19 16:29:16

标签: python python-internals

从学习python book第5版:

  

第421页,脚注2:

     

从技术上讲,I.__next__循环调用内部等效的next(I),而不是此处使用的I.__next__,尽管两者之间几乎没有任何区别。您的手动迭代通常可以使用任一呼叫方案。

这到底是什么意思?这是否意味着在str循环或任何内置迭代上下文中由C函数而不是for内置函数调用__str__

  

第914页:

     

print首先尝试str操作和print内置函数(运行__str__的内部等效函数)。它通常应返回用户友好的显示。

除了书之外,Python是否在内部使用C函数调用__next__ require('angular-timeline/dist/angular-timeline'); ,正如我从书中所理解的那样?

1 个答案:

答案 0 :(得分:5)

Python C实现使用本质上与Python函数相同的C函数,因为像str()next()这样的Python函数通常是围绕着C函数。

这些C函数然后负责调用右钩子;这可能是钩子的C版本(指向函数的结构中的槽),或类上的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类被大致相同。如果您想深入挖掘,Python文档包含full coverage of the C-API,包括dedicated tutorial

回到原来的两个函数,next()的内部等效项为PyIter_Next()str()用于任意对象的字符串转换,为PyObject_Str()