У меня есть код C ++, который вызывает DLL, которая содержит функции Python, написанные на Cythonized. Функции python работают с DataFrame (создайте его, а затем выполните поиск / прочее). Я хотел бы сделать создание DataFrame только один раз, что означает, что мне нужно сохранять его состояние после выхода из функции python.
Я не нашел способа вернуть указатель DataFrame из фабрики Cython в C ++ и отправить его из C ++ в другие функции Cython позже. Я хочу избежать синглтоноподобных решений в Cython. Пожалуйста, порекомендуйте.
Edit1:
foo.pyx:
cdef public string Foo( const string& csvpath ) except *:
cdef string c_csvpath = csvpath
#...
foo.h:
__PYX_EXTERN_C DL_IMPORT(std::string) Foo(std::string const &);
Я собираюсь предположить, что вы хотите сохранить string
возвращаемый тип (если нет, то вы можете просто вернуть объект Python, который вам может показаться более простым). Если это так, то вам нужно использовать один из аргументов функции для хранения данных. В принципе, можно использовать любой изменяемый объект Python, но я собираюсь продемонстрировать его со словарем, так как я думаю, что это имеет смысл:
cdef public string Foo( const string& csvpath, dict saved_data ) except *:
cdef string c_csvpath = csvpath
# get the DataFrame if possible, otherwise generate it
try:
df = saved_data['dataframe']
except KeyError:
df = 3.3 # somehow generate your dataframe# at the end make sure everything's updated
saved_data['dataframe'] = df
return csvpath
Подпись C становится:
__PYX_EXTERN_C DL_IMPORT(std::string) Foo(std::string const &, PyObject *);
В вашем коде C ++ вам нужно создать и сохранить словарь:
PyObject* data = PyDict_New();
// good code would check for null here
string out = Foo(string("Hi"),data);
// your data dictionary should now have "dataframe" in it
// a second call, reusing the data frame
string out2 = Foo(string("Hi"),data);
// once you're sure you've done with the data frame
Py_DECREF(data); // frees it, unless Python also has a copy
Других решений пока нет …