[英]IronPython integration in C#: a specific problem/question
I'm working on providing an extensibility mechanism for my C# mapmaking application through IronPython. 我正在通过IronPython为我的C#mapmaking应用程序提供可扩展性机制。 Everything works fine, but I have a specific requirement which I'm having trouble implementing: I want the user to be able to specify two things:
一切正常,但我有一个特定的要求,我无法实现:我希望用户能够指定两件事:
getTextLabel(element)
) getTextLabel(element)
) These two settings must be separate, but I don't know if it is possible to do this using PythonScript
and related classes. 这两个设置必须是分开的,但我不知道是否可以使用
PythonScript
和相关类来完成此操作。
I'm a newbie in Python, perhaps there is another way to achieve this? 我是Python的新手,或许有另一种方法可以实现这一目标? For performance reasons I want to avoid loading and compiling the Python script file several times (since there could be several above mentioned different "function call" settings and I want to reuse the
CompiledCode
instance for the file if possible). 出于性能原因,我想避免多次加载和编译Python脚本文件(因为可能存在上面提到的几个不同的“函数调用”设置,如果可能的话我想重用文件的
CompiledCode
实例)。
UPDATE: @digEmAll gave the correct answer to my question, so I'm accepting it as a valid answer. 更新: @digEmAll给出了我的问题的正确答案,所以我接受它作为一个有效的答案。 But if you are concerned with performance, you should also check out my own answer.
但如果你关心表现,你也应该看看我自己的答案。
You can do something like this: 你可以这样做:
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);
As long as you keep the scope
where the module is loaded, you can call functions of the module without reloading it. 只要保留模块加载的
scope
,就可以调用模块的功能而无需重新加载。
I've done some testing of @digEmAll's code. 我已经对@ digEmAll的代码进行了一些测试。 First I must say it runs correctly and does what I asked in the question.
首先,我必须说它运行正常,并按照我在问题中提出的要求。 But I was concerned with the fact that you have to call
但我担心你必须打电话
string expr = "functionOfMyModule()";
var result = engine.Execute(expr, scope);
every time you want to evaluate a user-defined expression. 每次要评估用户定义的表达式时。 My concern was that the code is not pre-compiled and has to be reparsed on each execution, which could have a serious effect on the performance of my application (these kinds of expressions could be called hundreds of thousands if not millions of times, so every millisecond counts).
我担心的是代码不是预编译的,必须在每次执行时重新解析,这可能会严重影响我的应用程序的性能(这些类型的表达式可能被称为数十万甚至数百万次,所以每毫秒计数)。
I tried a different solution: simply pasting the user-defined expression at the end of the Python module (I'm not saying this works in all situations!): 我尝试了一个不同的解决方案:简单地在Python模块的末尾粘贴用户定义的表达式(我不是说这适用于所有情况!):
def simpleFunc(x):
return x + 2;
# this is where the pasting occurs:
simpleFunc(x)
What I did then is to compile this code: 我当时做的是编译这段代码:
ScriptSource source = engine.CreateScriptSourceFromString(myCode);
CompiledCode compiledCode = source.Compile();
... create a scope and run it: ...创建一个范围并运行它:
ScriptScope scope = engine.CreateScope();
scope.SetVariable ("x", 10);
int result = compiledCode.Execute<int>(scope);
Now I executed both solutions (digEmAll's and my own) on the same piece of code and the same expression 10,000 times and here are the results: 现在,我在相同的代码片段和相同的表达式上执行了两个解决方案(digEmAll和我自己的),结果如下:
So I guess I'll try to use my own solution, unless the code pasting proves to be a problem. 所以我想我会尝试使用自己的解决方案,除非代码粘贴被证明是个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.