создать экземпляр класса python в C #, используя имя класса как строку

Этот вопрос SO предоставляет код для создания экземпляра класс python в C #.

Следующий код заставляет заранее знать имя функции python. Однако мне нужно указать имя класса и имя функции, которая должна выполняться строками.

ScriptEngine engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile("Calculator.py");
ScriptScope scope = engine.CreateScope();
source.Execute(scope);

dynamic class_object = scope.GetVariable("Calculator");
dynamic class_instance = class_object();
int result = class_instance.add(4, 5);  // I need to call the function by a string

person Santi Peñate-Vera    schedule 09.06.2016    source источник


Ответы (2)


Самый простой способ сделать это - установить пакет nuget с именем Dynamitey. Он был разработан специально для вызова динамических методов (и выполнения других полезных вещей) для динамических объектов. После установки просто выполните:

static void Main(string[] args)
{
    ScriptEngine engine = Python.CreateEngine();
    ScriptSource source = engine.CreateScriptSourceFromFile("Calculator.py");
    ScriptScope scope = engine.CreateScope();
    source.Execute(scope);

    dynamic class_object = scope.GetVariable("Calculator");
    dynamic class_instance = class_object();
    int result = Dynamic.InvokeMember(class_instance, "add", 4, 5);
}

Если вы хотите знать, что он делает под капотом - он использует тот же код, который используется компилятором C # для динамических вызовов. Это длинная история, но если вы хотите прочитать об этом, вы можете сделать это например здесь.

person Evk    schedule 09.06.2016

Вы ищете методы Invoke и InvokeMember IronPython:

ScriptEngine engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile("Calculator.py");
ScriptScope scope = engine.CreateScope();
source.Execute(scope);

object class_object = scope.GetVariable("Calculator");
object class_instance = engine.Operations.Invoke(class_object);
object[] args = new object[2];
args[0] = 4;
args[1] = 5;
int result = (int)engine.Operations.InvokeMember(class_instance, "add", args);  // Method called by string
                                                                                //  "args" is optional for methods which don't require arguments.

Я также изменил тип dynamic на object, поскольку он вам больше не понадобится для этого примера кода, но вы можете оставить его, если вам понадобится вызвать некоторые методы с фиксированным именем.

person gog    schedule 11.10.2018