Python 如何辨别PyObject的类型?
我正在编写一个C函数,它将PyObject*作为参数,并根据数据类型对其进行处理。例如,如果是字符串、整数、双精度、列表等 我正在寻找检查数据类型的方法,你能给我举一些例子吗Python 如何辨别PyObject的类型?,python,Python,我正在编写一个C函数,它将PyObject*作为参数,并根据数据类型对其进行处理。例如,如果是字符串、整数、双精度、列表等 我正在寻找检查数据类型的方法,你能给我举一些例子吗 我正在使用CPython 3.8。您应该能够使用 PyObject*PyObject\u类型(PyObject*o) 当o为非空时,返回与该对象对应的类型对象 对象类型o。失败时,引发SystemError并返回NULL。 这相当于Python表达式type(o)。此函数 递增返回值的引用计数。真的没有 使用此函数而不是通
我正在使用CPython 3.8。您应该能够使用
PyObject*PyObject\u类型(PyObject*o)
当o为非空时,返回与该对象对应的类型对象
对象类型o。失败时,引发SystemError并返回NULL
。
这相当于Python表达式type(o)
。此函数
递增返回值的引用计数。真的没有
使用此函数而不是通用表达式的原因
o->ob_type
,返回类型为PyTypeObject*
的指针,除非
需要递增的引用计数
如果您想正确处理子类,您可能还需要研究一下。Python中的大多数内置类型都有相关的类型检查函数,您可以在中查找这些函数。例如,
PyLong\u Check
检查对象是否为int(接受子类),而PyLong\u CheckExact
执行相同的检查,但拒绝子类:
if (PyLong_Check(whatever)) {
// do int stuff
}
还有
类型
和isinstance
的C级等价物
要在C中访问对象的类型,可以使用。这提供了对对象类型的借用引用-相当于访问对象的ob_type
字段。该值的类型为PyTypeObject*
;如果需要,可以将其强制转换为PyObject*
或者,如果您需要新的参考,您可以使用。这将为您提供一个PyObject*
;如果需要,可以将其强制转换为PyTypeObject*
。(指针类型的差异与引用计数处理的差异无关。)
有两种方法可以在C级别执行isinstance,具体取决于您实际需要的内容。第一个是,它完全等同于
isinstance
,包括以isinstance
的方式处理虚拟子类和false\uuuuuuuuuuu属性,并作为第二个参数处理类的元组。这通常不是您在C级别真正想要的,因为通过PyObject\u IsInstance
测试并不能保证对象的内存布局
第二个是,它要求无论什么
都是什么类
的“具体”实例-无论什么
的实际类型必须是什么类
或什么类
的“真实”后代。这确保了whatever
具有实际的C级成员,即WhateverClass
的实例
例如,使用以下类:
import abc
class A(metaclass=abc.ABCMeta):
pass
class B: pass
A.register(B)
class C:
__class__ = int
b = B()
c = C()
PyObject\u-IsInstance(b,A)
和PyObject\u-IsInstance(c,int)
都是真的,但是PyObject\u-TypeCheck(b,A)
和PyObject\u-TypeCheck(c,int)
都是假的
特定于类型的类型检查宏,如PyLong\u check
的行为类似于PyObject\u TypeCheck
,而不是PyObject\u IsInstance
。它们忽略了虚拟子类和false\uu类
属性。您可以使用python中的type()
吗?答案很好。在什么情况下,您希望确保增加引用计数?这是为了防止类本身被垃圾收集吗?@flakes:与您希望增加任何其他对象的引用计数的情况完全相同:当您需要自己的新引用时,独立于原始引用。例如,如果要从正在编写的函数返回引用,通常需要确保它是新引用,而不是借用的引用。PyObject\u IsInstance
是否会在有元类的情况下返回python级代码?如果我理解正确,您可以使用元类在python中为此实现自定义实现。这与PyObject\u TypeCheck
不同吗?@flakes:PyObject\u IsInstance
将调用\uuu instancecheck\uuu
,这可能会调用Python级别的代码PyObject\u TypeCheck
不会调用Python级别的代码。