Я не смог найти способ встроить код Python, который устанавливает флаги в коде C++ в https://docs.python.org/3.5/extending/embedding.html.
У меня есть этот код Python test.py:
import tensorflow as tf
# Settings
flags = tf.app.flags
FLAGS = flags.FLAGS
#core params..
flags.DEFINE_string('model', 'gcn', 'model name')
flags.DEFINE_float('learning_rate', 0.01, 'initial learning rate')
flags.DEFINE_string("model_size", "small", "define model size")
def main(argv=None):
print("Flags Set")
print(FLAGS.learning_rate)
if __name__ == '__main__':
tf.app.run()
когда я выполняю команду:
python -m test --learning_rate 0.0002
Результат:
Flags Set
0.0002
Как я могу внедрить приведенный выше код Python в C++ и вызвать его?
Согласно описанию документа, встроенные функции кода Python необходимо вызывать через ./executable <python_module> <function> <аргументы функции>. Но когда я выполняю свой код Python отдельно, я хочу указать значения флага (например: --learning_rate 0,0002). Я не мог найти способ установить эти флаги, когда встраиваю код Python в С++.
Для начала взгляните на это: SO: Как получить доступ к глобальной переменной Python из C?. (Я гуглил с помощью google "найти конкретную переменную python c c++", чтобы найти это.) Должен признаться, мне потребовалось некоторое время, чтобы правильно объединить C++ и Python (и еще некоторое время, чтобы сделать его стабильным), но я использовал исключительно документацию по Python. или погуглите, чтобы освоить его. При небольшом терпении это возможно. ;-)
Может быть, я неправильно понял ваш вопрос. Если вы спросите, как передавать аргументы командной строки через функции PyRun_
-> я нашел это: SO: передать аргумент в PyRun_File(***) со ссылкой на эту статью в блоге: Передача параметров из C в Pyhton..
Несколько лет назад я использовал Boost.Python, чтобы добавить возможность написания сценариев в приложение на C++.
@wilx, не могли бы вы предложить мне хороший учебник, чтобы добавить возможности сценариев в приложение C++ с использованием Boost.Python?
У вас есть два варианта,
1. Просто запустите скрипт Python с помощью system(),
system("python -m /path/to/test.py --learning_rate 0.0002");
2. Используйте Python/C API следующим образом:
#include <python3.6/Python.h>
#include<iostream>
using namespace std;
int main(int argc, char *argv[])
{
FILE* file;
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
wchar_t** _argv;
for(int i=0; i<argc; i++){
wchar_t *arg = Py_DecodeLocale(argv[i], NULL);
_argv[i] = arg;
}
Py_SetProgramName(program);
Py_Initialize();
PySys_SetArgv(argc, _argv);
file = fopen("/path/to/test.py","r");
PyRun_SimpleFile(file, "/path/to/test.py");
Py_Finalize();
return 0;
}
Если вы получаете исполняемый файл в a.out, вы можете запустить его, как показано ниже:
./a.out --learning_rate 0.0002
Примечание:- У меня есть Python.h в папке python3.6m, и я использовал флаг -lpython3.6m для компиляции.
Большое спасибо. Я предпочитаю второй вариант. Тем не менее, я сделал небольшое изменение в приведенном выше коде. Я поставил Py_Initialize(); как первая строка основного метода. В противном случае я получил ImportError: нет модуля с именем «tensorflow».
Я бы проверил это, если бы у меня был тензорный поток, рад, что это сработало для вас.
если я возьму это основное содержимое метода в отдельную функцию и вызову эту функцию из двух потоков, я получу ошибку сегментации. У вас есть на это ответ?
Ваше первое предложение немного странное, поскольку вы ссылаетесь именно на документ. страница, которая объясняет, как это сделать. Код C++ обычно компилируется в двоичный код (хотя он может интерпретироваться так же хорошо, как я недавно узнал). Код Python обычно интерпретируется интерпретатором Python (хотя могут быть и такие компиляторы, как, например, ЖелезоПитон). Следовательно, это то, что док. описывает: Встраивание интерпретатора Python в программу C или C++. Код C++ также может расширять Python дополнительными типами, переменными и функциями для взаимодействия. Python и C++.