检查PyObject的C类型

5 投票
2 回答
8152 浏览
提问于 2025-04-16 18:12

我正在使用Python 3.2和C++。

我需要找出当前在一个PyObject中存储的是什么类型的C语言数据。我查阅了文档,也在网上搜索过,似乎没有其他人需要做这个。

所以我有一个PyObject,想要提取里面的C值。我知道需要用哪些函数来提取这个值,但我首先需要知道这个对象里到底存储的是什么,以便调用正确的函数。

为了帮助理解,这里有一些我正在尝试的示例代码。

//Variable is a custom variant type to allow for generic functionality.
Variable ExtractArgument( PyObject * arg )
{
  Variable value;
  PyObject* result;
  //now here is the problem, I need to know which Python function to call in order to
  //extract the correct type;
  value = PyLong_FromLong( arg );
  //or 
  value = PyFloat_FromDouble( arg )
  //ect.
  return value;
}

希望我能得到一些看起来像这样的东西。

Variable ExtractArgument( PyObject * arg )
{
  Variable value;
  PyObject* result;
  //PyType is not the actual variable to that holds the type_macro, GetType should be
  //replaced by the function I am trying to find 
  PyType type = GetType( arg ); 
  switch( type )
  { 
    case T_INT: value = static_cast<int>(PyLong_FromLong( arg  )); 
      break;
    case T_FLOAT: value = static_cast<float>(PyFloat_FromDouble( arg  ));
      break;
    case T_DOUBLE: value = PyDouble_FromDouble( arg );
      break;
    //ect.
  }
  return value;
} 

抱歉如果这个问题太长,或者信息太多。这是我第一次发帖,不想遗漏任何可能有帮助的内容。感谢你能给我提供的任何帮助或见解。

2 个回答

1

Python的类型和C语言的类型并不是一一对应的关系。也就是说,没有一个Python的C/API函数可以告诉你某个特定的值适合用哪个C类型。不过,有一些函数,比如PyFloat_Check()PyInt_Check(),可以用来检查类型(而且它们也会考虑子类)。另外,还有一些参数说明符可以用在PyArg_ParseTuple()(以及它的变种)中,告诉Python如何正确地转换传入的参数。

通常我们会使用后者;也就是用PyArg_ParseTuple()来解析传给C函数的参数。如果你需要不同类型的参数以不同的方式处理,可以把它们作为不同的参数传入(通常是命名参数)。不过,这种方法是否适合你还不太清楚。第二种常见的做法是尝试用不同的函数来转换参数,而不先进行类型检查,如果一个转换失败了,就直接尝试另一个转换函数。显式的类型检查通常是最不常见的选择。

5

Python中的对象没有C语言那种类型,它们有自己的Python类型。比如,一个整数在C语言中可以是长整型或长整型整数。你可以用 PyInt_Check(obj)PyList_Check(obj) 等函数来检查对象的类型。如果返回结果是对的,那就说明你有一个这种类型的对象。

需要注意的是,像 PyLong_FromLong 这样的函数是反过来的。它们是把C语言的值转换成PyObject*类型。所以你可能是搞错了,应该用 PyInt_AsLong

撰写回答