2011-05-23 51 views
4

我正在使用Python 3.2和C++。检查PyObjects 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; 
} 

很抱歉,如果这个问题是长期或过多的信息。第一次发布,不想留下任何可能有帮助的东西。 感谢您对此问题给予的任何帮助或见解。

回答

4

Python对象没有C类型,它们有一个Python类型。例如,整数可以是C长整数或长整数。你可以用PyInt_Check(obj)PyList_Check(obj)等来检查类型。如果返回true,那么你知道你有这种类型的对象。

请注意PyLong_FromLong等等就是另一种方式。他们取一个C值并将它变成一个PyObject *。所以你正在使用它们。我想你的意思是PyInt_AsLong

+0

是的,我的意思是PyInt。 – DaneEC117 2011-05-23 23:00:41

+0

这似乎是迄今为止我必须尝试的最佳选择。我“可能”遇到了一些类型冲突,因为python并没有存储我需要的所有类型,所以我很可能会结合检查C++函数期望的类型来执行此操作。 – DaneEC117 2011-05-23 23:08:16

+0

你正在编写一个C++函数的Python包装器吗?听起来你正在重新发明SWIG。 – Adam 2011-05-23 23:11:13

1

这不是Python类型的工作方式;它们不会映射到C类型的一对一。没有Python C/API函数可以告诉你特定值将适用于哪种C类型。但是,有些功能,如PyFloat_Check()PyInt_Check()可以检查类型(也可以考虑子类)。还有PyArg_ParseTuple()的说明符(及其变体)告诉Python适当地转换传入的参数。

通常使用的是后者;使用PyArg_ParseTuple()解码传递给C函数的参数,如果需要以不同方式处理不同类型的对象,请将它们作为不同的参数传递(通常作为命名参数)。不清楚这种方法是否适用于您。第二个最常见的做法是尝试使用不同函数来转换参数,而不先进行类型检查,并且只在一个失败时尝试另一个转换函数。明确的类型检查通常是最不常见的选择。

+0

是的,正如我所说的,使用'PyArg_ParseTuple()'和不同的类型,您需要一些预先区分预期类型的​​方法。这实际上是Python中一个非常常见的主题。也许你想改变你的类来实际存储预期的C类型以及PyObject的值。否则,你会遇到一些问题,例如,在你的代码中,int'1'不是一个'float'参数的有效值,但是在其他地方都非常好。 – 2011-05-23 23:06:22

+0

那么从亚当说,它看起来像我会做像PyInt_Check,PyFloat_Check等类型检查。然后在从这个语句中得到真或假之后,检查我使用的元类型(它定义像int,unsigned,float,double等等)的变量。接下来是相应的python调用,比如PyInt_AsLong,PyFloat_AsDouble等。和适当的演员。 – DaneEC117 2011-05-23 23:30:43

+0

是的,这也是我描述的事情之一,它也有缺点(就像我描述的那样)。 – 2011-05-23 23:35:05