Я пытаюсь импортировать модуль на С++; модуль находится в пакете и должен быть доступен следующим образом:
from x.y import class1,func1, const1, etc
Я использую Python 3.6, и для этой версии я нашел, что нужно использовать PyRun_SimpleString
для импорта, а затем использовать PyImport_AddModuleObject
для обработки моего модуля. то есть:
PyRun_SimpleString("from PacKage1 import Module1 as Module1");
auto module = PyImport_AddModuleObject(PyUnicode_DecodeFSDefault("Module1"));
так что в будущем я могу получить доступ к его различным атрибутам, что-то вроде этого:
auto args = Py_BuildValue("sOOOOONNiN", model_name, model_checkpoint_path, align_fn,
bank_folder_root, cache_folder, postfix,
rebuild_cache, use_jit, threshold, device);
if (module != nullptr) {
// dict is a borrowed reference.
auto pdict = PyModule_GetDict(module);
if (pdict == nullptr) {
cout << "Fails to get the dictionary.\n";
return 1;
}
//Py_DECREF(module);
PyObject *pKeys = PyDict_Keys(pdict);
PyObject *pValues = PyDict_Values(pdict);
map<string, string> my_map;
//cout << "size: " << PyDict_Size(pdict)<<endl;
char* cstr_key = new char[100];
char* cstr_value = new char[500];
for (Py_ssize_t i = 0; i < PyDict_Size(pdict); ++i) {
PyArg_Parse(PyList_GetItem(pKeys, i), "s", &cstr_key);
PyArg_Parse(PyList_GetItem(pValues, i), "s", &cstr_value);
//cout << cstr<< " "<< cstr2 <<endl;
my_map.emplace(cstr_key, cstr_value);
}
for (auto x : my_map)
{
cout << x.first << " : " << x.second << endl;
}
system("pause");
// Builds the name of a callable class
auto python_class = PyDict_GetItemString(pdict, "MyClass1");
system("pause");
if (python_class == nullptr) {
cout << "Fails to get the Python class.\n";
return 1;
}
//Py_DECREF(pdict);
cout << python_class;
PyObject* object;
// Creates an instance of the class
if (PyCallable_Check(python_class)) {
object = PyObject_CallObject(python_class, args);
Py_DECREF(python_class);
}
else {
std::cout << "Cannot instantiate the Python class" << endl;
Py_DECREF(python_class);
return 1;
}
auto val = PyObject_CallMethod(object, "is_jit_model_available", NULL);
if (!val)
cout << "error!";
cout << val;
Когда я пытаюсь запустить этот код, я получаю этот вывод, который показывает содержимое карт:
size: 5
__doc__ : Module1
__loader__ : Module1
__name__ : Module1
__package__ : Module1
__spec__ : Module1
Итак, это результат PyModule_GetDict(module);
Однако, когда дело доходит до извлечения класса из этого модуля, происходит сбой, то есть PyDict_GetItemString(pdict, "MyClass1");
возвращает null
.
Мне кажется, что сам обработчик модуля неверен, и это, вероятно, потому, что, возможно, он не указывает на фактический модуль, что означает, что я полностью не смог импортировать и получить дескриптор этого модуля.
Поэтому я не могу придумать никакого другого способа, который позволил бы мне импортировать модуль и использовать его таким образом.
Что мне здесь не хватает?
PyImport_ImportModule
при поиске вариантов? - person user2357112 supports Monica   schedule 25.03.2020PyObject *module = PyImport_ImportModule("packagename.submodulename");
. То, что вы делаете, действительно странно и не дает желаемого эффекта - вы создаете новый объект модуля для несуществующего модуля, совершенно не связанного с тем, который вы хотите. - person user2357112 supports Monica   schedule 25.03.2020PyImport_AddModuleObject
, а неPyImport_ImportModule
. Я предположил, что когда я импортировал модуль с помощьюPyRun_SimpleString
, я могу получить его дескриптор с помощьюPyImport_AddModuleObject
. по крайней мере, это то, что понял из документов! - person Rika   schedule 25.03.2020