Как я могу вызвать (железный) код Python из приложения C #? - PullRequest
50 голосов
/ 14 августа 2011

Есть ли способ вызова кода Python, используя, как я полагаю, IronPython из C #?Если да, то как?

Ответы [ 2 ]

111 голосов
/ 15 августа 2011

Процесс прост, особенно в приложении C # /. NET 4, где поддержка динамических языков была улучшена за счет использования типа dynamic.Но в конечном итоге все зависит от того, как вы собираетесь использовать (Iron) Python-код в своем приложении.Вы всегда можете запустить ipy.exe как отдельный процесс и передать исходные файлы, чтобы они могли быть выполнены.Но вы, вероятно, хотели разместить их в своем приложении C #.Это оставляет вам много вариантов.

  1. Добавить ссылку на сборки IronPython.dll и Microsoft.Scripting.dll.Обычно они находятся в корневом каталоге установки IronPython.

  2. Добавьте using IronPython.Hosting; в начало вашего исходного кода и создайте экземпляр механизма сценариев IronPython, используя Python.CreateEngine().

  3. У вас есть несколько вариантов отсюда, но в основном вы должны создать ScriptScope или ScriptSource и сохранить его как переменную dynamic.Это позволяет вам выполнить его или управлять областями из C #, если вы решите это сделать.

Опция 1:

Использование CreateScope() для создания пустого ScriptScope использовать непосредственно в коде C #, но можно использовать в исходниках Python.Вы можете думать о них как о своих глобальных переменных в экземпляре интерпретатора.

dynamic scope = engine.CreateScope();
scope.Add = new Func<int, int, int>((x, y) => x + y);
Console.WriteLine(scope.Add(2, 3)); // prints 5

Опция 2:

Использование Execute() для выполнения любого кода IronPython в строке.Вы можете использовать перегрузку, где вы можете передать ScriptScope для хранения или использования переменных, определенных в коде.

var theScript = @"def PrintMessage():
    print 'This is a message!'

PrintMessage()
";

// execute the script
engine.Execute(theScript);

// execute and store variables in scope
engine.Execute(@"print Add(2, 3)", scope);
// uses the `Add()` function as defined earlier in the scope

Опция 3:

Использование ExecuteFile() для выполнения IronPythonисходный файл.Вы можете использовать перегрузку, где вы можете передать ScriptScope для хранения или использования переменных, определенных в коде.

// execute the script
engine.ExecuteFile(@"C:\path\to\script.py");

// execute and store variables in scope
engine.ExecuteFile(@"C:\path\to\script.py", scope);
// variables and functions defined in the scrip are added to the scope
scope.SomeFunction();

Опция 4:

Использование GetBuiltinModule() или ImportModule() метод расширения для создания области, содержащей переменные, определенные в указанном модуле.Модули, импортированные таким образом, должны быть установлены в путях поиска.

dynamic builtin = engine.GetBuiltinModule();
// you can store variables if you want
dynamic list = builtin.list;
dynamic itertools = engine.ImportModule("itertools");
var numbers = new[] { 1, 1, 2, 3, 6, 2, 2 };
Console.WriteLine(builtin.str(list(itertools.chain(numbers, "foobar"))));
// prints `[1, 1, 2, 3, 6, 2, 2, 'f', 'o', 'o', 'b', 'a', 'r']`

// to add to the search paths
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\path\to\modules");
engine.SetSearchPaths(searchPaths);

// import the module
dynamic myModule = engine.ImportModule("mymodule");

Вы можете сделать довольно много, размещая код Python в своих проектах .NET.C # помогает преодолеть этот разрыв легче справиться.Комбинируя все варианты, упомянутые здесь, вы можете делать практически все, что захотите.Конечно, вы можете сделать больше с классами из пространства имен IronPython.Hosting, но этого должно быть более чем достаточно для начала работы.

2 голосов
/ 04 декабря 2018

Чтобы запустить функцию, вы не можете вызывать ее, как в варианте 3 ответа Джеффа Меркадо (который является отличным и очень полезным! Но эта опция не компилируется, по крайней мере, в .NET 4.5). Вы можете использовать ScriptScope.GetVariable, чтобы получить фактическую функцию, а затем вы можете вызвать ее как функцию C #. Используйте это так:

C # код:

var var1,var2=...
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
engine.ExecuteFile(@"C:\test.py", scope);
dynamic testFunction = scope.GetVariable("test_func");
var result = testFunction(var1,var2);

Код Python:

def test_func(var1,var2):
    ...do something...

Мне потребовалось некоторое время, чтобы наконец понять это, и это довольно просто ... Жаль, что нет хорошей документации IronPython. Надеюсь, это поможет:)

...