【问题标题】:How can I call (Iron)Python code from a C# app?如何从 C# 应用程序调用 (Iron)Python 代码?
【发布时间】:2011-10-26 13:26:25
【问题描述】:

有没有办法使用我假设的 IronPython 从 C# 调用 Python 代码?如果有,怎么做?

【问题讨论】:

  • C# 4.0 dynamic 关键字的重要原因之一。你有吗?重要。

标签: c# python ironpython


【解决方案1】:

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

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

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

  3. 这里有几个选项,但基本上你会创建一个ScriptScopeScriptSource 并将其存储为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");

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

【讨论】:

  • engine = Python.CreateEngine() 也是需要的
【解决方案2】:

要运行一个函数,您不能像 Jeff Mercado 的响应的选项 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 文档。希望这会有所帮助:)

【讨论】:

    【解决方案3】:

    1) 需要安装

    Install-Package DynamicLanguageRuntime -Version 1.2.2
    

    2) 需要使用这个添加“Iropython.dll”:https://www.webucator.com/how-to/how-add-references-your-visual-studio-project.cfm

    3) 需要使用

    using IronPython.Hosting;
    using IronPython.Runtime;
    using IronPython;
    using Microsoft.Scripting.Hosting;
    using Microsoft.Scripting;
    

    3) 需要设置var

    ScriptEngine engine = Python.CreateEngine();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-15
      • 2013-02-06
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      • 2010-10-24
      相关资源
      最近更新 更多