2011-05-23 74 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