当我看到len函数的C实现时,我正在阅读python内置函数的实现
static PyObject *
builtin_len(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=fa7a270d314dfb6c input=bc55598da9e9c9b5]*/
{
Py_ssize_t res;
res = PyObject_Size(obj);
if (res < 0) {
assert(PyErr_Occurred());
return NULL;
}
return PyLong_FromSsize_t(res);
我不明白这段代码是怎么回事。我不知道C是怎么工作的。有人能解释一下这个代码在做什么吗?在
我从https://github.com/python/cpython/blob/master/Python/bltinmodule.c得到代码
编辑:我只是好奇len函数怎么这么快,偶然发现了这段代码。我只想知道为什么函数PyObject_Size被用来检查object的大小是0,然后PyLong_FromSsize t返回实际大小。在
这个函数没有什么特别之处。通常用C编写的函数,特别是那些不调用Python代码的函数,比用Python编写的函数快得多。在
我在这里特别采取的立场是,一个读者知道C是如何工作的,否则解释应该是一本书。在
builtin_len
是在Python代码中执行len(foo)
时调用的函数。函数的PyObject *obj
参数引用作为参数(foo
)给定的对象,PyObject *self
将包含对{Python中的每个容器的长度必须介于0和}获取给定对象的大小。一旦出现错误,就会将当前线程的异常设置为引发,并返回一个数字<;0(-1)。在
Py_ssize_t
允许的最大值之间。PyObject_Size(obj);
是一个函数/宏,它通过obj->ob_type->tp_as_sequence->sq_length
或{return NULL;
表示调用方发生了异常,它必须相应地执行-如果它是Python字节码中的函数调用指令,它将引发异常;如果它是C代码,那么它的行为方式与此函数类似-如果发生异常,则返回NULL或无效值;或者它可以清除异常或者用另一个异常替换它。在否则,如果大于或等于0,则C整数类型的
Py_ssize_t res
将转换为Pythonint
对象,方法是返回一个现有的int
对象。由于历史原因,Pythonint
对象在cpython3中被称为PyLong
。PyLong_FromSsize_t()
是许多函数中的一个-这个函数能够将Py_ssize_t
类型的任何值转换为具有相同值的Pythonint
。与所有其他对象一样,对该对象的引用作为指向(半不透明)PyObject
结构的指针而保留,并返回此值。在assert(PyErr_Occurred());
是一个仅在Python调试版本中有效的断言。它断言,当从PyObject_Size
获得一个负数时,表示异常正在被抛出,那么异常也已被正确设置;如果不存在,它将直接中止整个CPython进程。它在Python的发布版本中不起作用,因为“断言永不失败”。在相关问题 更多 >
编程相关推荐