Python C-API:在字典中使用'PySequence_Length'
我试图使用Python C-API:在字典中使用'PySequence_Length',python,python-3.x,cpython,python-c-api,Python,Python 3.x,Cpython,Python C Api,我试图使用PySequence\u Length获得C语言中Python字典的长度。我意识到我可以使用PyDict\u Size,但我对在某些上下文中使用更通用的函数感兴趣 PyObject* d = PyDict_New(); Py_ssize_t res = PySequence_Length(d); printf("Result : %ld\n", res); if (res == -1) PyErr_Print(); 此操作失败,并打印错误: TypeError:类型为“dict”的
PySequence\u Length
获得C语言中Python字典的长度。我意识到我可以使用PyDict\u Size
,但我对在某些上下文中使用更通用的函数感兴趣
PyObject* d = PyDict_New();
Py_ssize_t res = PySequence_Length(d);
printf("Result : %ld\n", res);
if (res == -1) PyErr_Print();
此操作失败,并打印错误:
TypeError:类型为“dict”的对象没有len()
我的问题是:为什么会失败?虽然Python字典对象不支持序列协议,但forPySequence\u Length
表示:
Py_ssize_t PySequence_长度(PyObject*o)
成功时返回顺序为o的对象数,成功时返回顺序为-1的对象数
失败对于不提供序列协议的对象,这是
相当于Python表达式len(o)
由于字典类型确实有一个\uuu len\uuu
属性,而且表达式len(d)
(其中d
是一个字典)正确地返回Python中的长度,我不明白为什么PySequence\u length
在C中会失败
有什么解释吗?这里的文档不正确吗?文档有误导性,是的。dict不是序列,即使它实现了序列协议的某些部分(对于包含测试,它是序列协议的一部分)。Python/C类型API中的这种特殊区别是不幸的,但它是几十年前设计选择的产物。文件反映了这一区别,尽管以同样尴尬的方式。它试图说的是,对于Python类来说,它与
len(o)
是一样的,不管Python类假装是什么。对于C类型,如果该类型未实现sizefunc的序列版本,PySequence_Length()
将引发异常,甚至不会考虑该类型是否具有sizefunc的映射版本
如果不能完全确定是否有序列,则应使用
PyObject\u Size()
。事实上,几乎没有理由调用PySequence_Length()
;通常,您要么知道类型(因为您刚刚创建了它,并且可以调用特定于类型的长度函数或宏,如PyList\u GET\u SIZE()
),要么甚至不知道它是否是一个序列。文档是误导性的,是的。dict不是序列,即使它实现了序列协议的某些部分(对于包含测试,它是序列协议的一部分)。Python/C类型API中的这种特殊区别是不幸的,但它是几十年前设计选择的产物。文件反映了这一区别,尽管以同样尴尬的方式。它试图说的是,对于Python类来说,它与len(o)
是一样的,不管Python类假装是什么。对于C类型,如果该类型未实现sizefunc的序列版本,PySequence_Length()
将引发异常,甚至不会考虑该类型是否具有sizefunc的映射版本
如果不能完全确定是否有序列,则应使用PyObject\u Size()
。事实上,几乎没有理由调用PySequence_Length()
;通常,您要么知道类型(因为您刚刚创建了它,可以调用特定于类型的长度函数或宏,如PyList\u GET\u SIZE()
),要么甚至不知道它是否是序列