Я получаю PyObject от вызова модуля Python 3.6, но не знаю, что в нем. Запуская тот же модуль Python в интерактивном режиме, я могу записать вывод и отобразить его примерно так:
> >>> from pfrunner import *
> >>> r = runpf(case14())
> >>> r ({'version': '2', 'baseMVA': 100.0, 'bus': array([[ 1. , 3. , 0. , 0. ,
> 0. , 0. , 1. , 1.06 ,
> 0. , 0. , 1. , 1.06 , 0.94 ],
> [ 2. , 2. , 21.7 , 12.7 ,
> 0. , 0. , 1. , 1.045 ,
> -4.98258914, 0. , 1. , 1.06 , 0.94 ], ...
> [ 2.00000000e+00, 0.00000000e+00, 0.00000000e+00,
> 3.00000000e+00, 1.00000000e-02, 4.00000000e+01,
> 0.00000000e+00]])}}, 'et': 0.12494635581970215, 'success': 1}, 1)
Итак, я написал метод, который «должен» рекурсивно деконструировать PyObject и распечатать его содержимое, но это не так. Все, что я получаю, это кортеж за кортежем после кортежа, но нет данных ни в одном кортеже. Я начинаю задумываться, понимаю ли я кортежи!
Вот метод:
void PowerFlow::printPyObject(PyObject *myPyObject) {
/* @todo Get this to actually work for complex data types! */
static size_t depth = 0; //track how far we descend into the object
Py_ssize_t pos;
PyObject* myData;
const char* s;
cout << string(depth, ' ') + "myPyObject address: " << (int)myPyObject << endl;
//process based on the object type
//Note: really bad case/switch statement :-(
//null
if (myPyObject == NULL || myPyObject == Py_None) {
//do nothing, empty object
}
//string
else if (PyUnicode_Check(myPyObject)) {
string myString;
myString = PyUnicode_AsUTF8(myPyObject);
cout << string(depth, ' ') + "string: " << myString << endl;
}
//bool
else if (PyBool_Check(myPyObject)) {
bool myBool;
myBool = (myPyObject == Py_True);
cout << string(depth, ' ') + "bool: " << myBool << endl;
}
//float
else if (PyFloat_Check(myPyObject)) {
double myFloat;
myFloat = PyFloat_AsDouble(myPyObject);
cout << string(depth, ' ') + "float: " << myFloat << endl;
}
//long (integer)
else if (PyLong_Check(myPyObject)) {
long myInt;
myInt = PyLong_AsLong(myPyObject);
cout << string(depth, ' ') + "long: " << myInt << endl;
}
//tuple
else if (PyTuple_Check(myPyObject)) {
/* @todo Get tuples to work */
depth++;
cout << string(depth, ' ') + "tuple: " << endl;
//iterate through all items in the tuple
int tsize = PyTuple_Size(myPyObject);
for (int pos = 0; pos < tsize; pos++) {
myData = PyTuple_GetItem(myPyObject, pos);
//int thisInt = PyLong_AsLong(myData);
//cout << "item " << pos << ": " << thisInt << endl;
Py_INCREF(myData);
printPyObject(myData);
Py_DECREF(myData);
}
depth--;
}
//list
else if (PyList_Check(myPyObject)) {
/* @todo get lists to work */
depth++;
cout << string(depth, ' ') + "list: " << endl;
//iterate through all items in the list
int tsize = PyList_Size(myPyObject);
for (int pos = 0; pos < tsize; pos++) {
myData = PyList_GetItem(myPyObject, pos);
//int thisInt = PyLong_AsLong(myData);
//cout << "item " << pos << ": " << thisInt << endl;
Py_INCREF(myData);
printPyObject(myData);
Py_DECREF(myData);
}
depth--;
}
//dict
else if (PyDict_Check(myPyObject)) {
/* @todo get dicts to work */
depth++;
cout << string(depth, ' ') + "dict: " << endl;
//iterate through all items in the dict
PyObject *key, *value;
Py_ssize_t dpos = 0;
while (PyDict_Next(myPyObject, &dpos, &key, &value)) {
Py_INCREF(key);
Py_INCREF(value);
printPyObject(key);
printPyObject(value);
Py_DECREF(key);
Py_DECREF(value);
}
depth--;
}
}
Похоже, myPyObject [0] — это еще один кортеж, каждый раз, навсегда …
Вот вывод:
myPyObject address: 10260392
tuple:
myPyObject address: 98891016
tuple:
myPyObject address: 98901608
tuple:
myPyObject address: 98901768
tuple:
myPyObject address: 98938672
tuple:
myPyObject address: 98936112
tuple:
myPyObject address: 98936272
tuple:
myPyObject address: 98938712
Как я могу получить значения в кортежах, диктовках, списках и т. Д. И выполнить рекурсию через PyObject?
Задача ещё не решена.
Других решений пока нет …