IronPython在C#中的集成:一个特定的问题/问题

时间:2011-03-13 21:03:49

标签: c# ironpython

我正在通过IronPython为我的C#mapmaking应用程序提供可扩展性机制。一切正常,但我有一个特定的要求,我在实现时遇到了麻烦:我希望用户能够指定两件事:

  1. 要加载的Python脚本的文件名
  2. 包含Python脚本的单行字符串,通常是从该Python文件调用函数(例如getTextLabel(element)
  3. 这两个设置必须是分开的,但我不知道是否可以使用PythonScript及相关类来执行此操作。

    我是Python的新手,或许有另一种方法可以实现这一目标?出于性能原因,我想避免多次加载和编译Python脚本文件(因为可能存在上面提到的几个不同的“函数调用”设置,并且如果可能的话我想重用文件的CompiledCode实例)。 / p>

    更新: @digEmAll 给出了我的问题的正确答案,所以我接受它作为一个有效的答案。但是如果你关心表现,你也应该看看我自己的答案。

2 个答案:

答案 0 :(得分:5)

您可以这样做:

string importScript = "import sys" + Environment.NewLine +
                      "sys.path.append( r\"{0}\" )" + Environment.NewLine +
                      "from {1} import *";

// python script to load
string fullPath = @"c:\path\mymodule.py";

var engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();

// import the module
string scriptStr = string.Format(importScript,
                                 Path.GetDirectoryName(fullPath),
                                 Path.GetFileNameWithoutExtension(fullPath));
var importSrc = engine.CreateScriptSourceFromString(scriptStr,Microsoft.Scripting.SourceCodeKind.File);
importSrc.Execute(scope);

// now you ca execute one-line expressions on the scope e.g.
string expr = "functionOfMyModule()";
var result = engine.Execute(expr, scope);

只要保持模块加载的scope,就可以调用模块的函数而无需重新加载。

答案 1 :(得分:4)

我已经对 @ digEmAll的代码进行了一些测试。首先,我必须说它运行正常,并按照我在问题中提出的要求。但我担心你必须打电话

string expr = "functionOfMyModule()";
var result = engine.Execute(expr, scope);

每次要评估用户定义的表达式时。我担心的是代码不是预编译的,必须在每次执行时重新解析,这可能会严重影响我的应用程序的性能(这些类型的表达式可能被称为数十万甚至数百万次,所以每毫秒都很重要。)

我尝试了另一种解决方案:简单地在Python模块的末尾粘贴用户定义的表达式(我并不是说这适用于所有情况!):

def simpleFunc(x):
    return x + 2;

# this is where the pasting occurs:
simpleFunc(x)

我所做的就是编译这段代码:

 ScriptSource source = engine.CreateScriptSourceFromString(myCode);
 CompiledCode compiledCode = source.Compile();

...创建一个范围并运行它:

 ScriptScope scope = engine.CreateScope();
 scope.SetVariable ("x", 10);
 int result = compiledCode.Execute<int>(scope);

现在我在同一段代码和相同的表达式上执行了两个解决方案(digEmAll和我自己的解决方案)10,000次,结果如下:

  • engine.Execute(expr,scope):0.29 ms / run
  • compiledCode.Execute(范围):0.01 ms / run

所以我想我会尝试使用我自己的解决方案,除非代码粘贴被证明是个问题。