如何从C#应用程序中调用(Iron)Python代码?

时间:2020-12-20 03:14:40

Is there a way to call Python code, using IronPython I assume, from C#? If so, how?

有没有办法用C#调用Python代码,我假设使用IronPython?如果是这样,怎么样?

1 个解决方案

#1


100  

The process is simple, especially in a C#/.NET 4 application where support for dynamic languages have been improved via usage of the dynamic type. But it all ultimately depends on how you intend to use the (Iron)Python code within your application. You could always run ipy.exe as a separate process and pass your source files in so they may be executed. But you probably wanted to host them in your C# application. That leaves you with many options.

这个过程很简单,特别是在C#/ .NET 4应用程序中,通过使用动态类型来改进对动态语言的支持。但这最终取决于您打算如何在应用程序中使用(Iron)Python代码。您始终可以将ipy.exe作为单独的进程运行并传递源文件,以便它们可以执行。但您可能希望在C#应用程序中托管它们。这给你留下了很多选择。

  1. Add a reference to the IronPython.dll and Microsoft.Scripting.dll assemblies. You'll usually find them both in your root IronPython installation directory.

    添加对IronPython.dll和Microsoft.Scripting.dll程序集的引用。您通常会在根IronPython安装目录中找到它们。

  2. Add using IronPython.Hosting; to the top of your source and create an instance of the IronPython scripting engine using Python.CreateEngine().

    使用IronPython.Hosting添加;到源代码的顶部,使用Python.CreateEngine()创建IronPython脚本引擎的实例。

  3. You have a couple of options from here but basically you'd create a ScriptScope or ScriptSource and store it as a dynamic variable. This allows you to execute it or manipulate the scopes from C# if you choose to do so.

    你有几个选项,但基本上你创建一个ScriptScope或ScriptSource并将其存储为动态变量。如果您选择这样做,这允许您执行它或从C#操作范围。

Option 1:

Using CreateScope() to create an empty ScriptScope to use directly in C# code but usable in Python sources. You can think of these as your global variables within an instance of the interpreter.

使用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

Option 2:

Using Execute() to execute any IronPython code in a string. You can use the overload where you may pass in a ScriptScope to store or use variables defined in the code.

使用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

Option 3:

Using ExecuteFile() to execute an IronPython source file. You can use the overload where you may pass in a ScriptScope to store or use variables defined in the code.

使用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();

Option 4:

Using GetBuiltinModule() or the ImportModule() extension method to create a scope containing the variables defined in said module. Modules imported this way must be set in the search paths.

使用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");

You can do quite a lot hosting Python code in your .NET projects. C# helps bridging that gap easier to deal with. Combining all the options mentioned here, you can do just about anything you want. There's of course more you can do with the classes found in the IronPython.Hosting namespace, but this should be more than enough to get you started.

你可以在.NET项目中做很多托管Python代码。 C#有助于弥合这个差距更容易处理。结合这里提到的所有选项,您可以做任何你想要的事情。当然,您可以使用IronPython.Hosting命名空间中的类进行更多操作,但这应该足以让您入门。

#1


100  

The process is simple, especially in a C#/.NET 4 application where support for dynamic languages have been improved via usage of the dynamic type. But it all ultimately depends on how you intend to use the (Iron)Python code within your application. You could always run ipy.exe as a separate process and pass your source files in so they may be executed. But you probably wanted to host them in your C# application. That leaves you with many options.

这个过程很简单,特别是在C#/ .NET 4应用程序中,通过使用动态类型来改进对动态语言的支持。但这最终取决于您打算如何在应用程序中使用(Iron)Python代码。您始终可以将ipy.exe作为单独的进程运行并传递源文件,以便它们可以执行。但您可能希望在C#应用程序中托管它们。这给你留下了很多选择。

  1. Add a reference to the IronPython.dll and Microsoft.Scripting.dll assemblies. You'll usually find them both in your root IronPython installation directory.

    添加对IronPython.dll和Microsoft.Scripting.dll程序集的引用。您通常会在根IronPython安装目录中找到它们。

  2. Add using IronPython.Hosting; to the top of your source and create an instance of the IronPython scripting engine using Python.CreateEngine().

    使用IronPython.Hosting添加;到源代码的顶部,使用Python.CreateEngine()创建IronPython脚本引擎的实例。

  3. You have a couple of options from here but basically you'd create a ScriptScope or ScriptSource and store it as a dynamic variable. This allows you to execute it or manipulate the scopes from C# if you choose to do so.

    你有几个选项,但基本上你创建一个ScriptScope或ScriptSource并将其存储为动态变量。如果您选择这样做,这允许您执行它或从C#操作范围。

Option 1:

Using CreateScope() to create an empty ScriptScope to use directly in C# code but usable in Python sources. You can think of these as your global variables within an instance of the interpreter.

使用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

Option 2:

Using Execute() to execute any IronPython code in a string. You can use the overload where you may pass in a ScriptScope to store or use variables defined in the code.

使用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

Option 3:

Using ExecuteFile() to execute an IronPython source file. You can use the overload where you may pass in a ScriptScope to store or use variables defined in the code.

使用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();

Option 4:

Using GetBuiltinModule() or the ImportModule() extension method to create a scope containing the variables defined in said module. Modules imported this way must be set in the search paths.

使用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");

You can do quite a lot hosting Python code in your .NET projects. C# helps bridging that gap easier to deal with. Combining all the options mentioned here, you can do just about anything you want. There's of course more you can do with the classes found in the IronPython.Hosting namespace, but this should be more than enough to get you started.

你可以在.NET项目中做很多托管Python代码。 C#有助于弥合这个差距更容易处理。结合这里提到的所有选项,您可以做任何你想要的事情。当然,您可以使用IronPython.Hosting命名空间中的类进行更多操作,但这应该足以让您入门。