IronPython DLR;将参数传递给编译代码?

时间:2011-01-31 15:03:05

标签: c# .net ironpython dynamic-language-runtime

我目前正在使用DLR创建并执行一个简单的python计算:

ScriptRuntime runtime = Python.CreateRuntime();
ScriptEngine engine = runtime.GetEngine("py");

MemoryStream ms = new MemoryStream();
runtime.IO.SetOutput(ms, new StreamWriter(ms));

ScriptSource ss = engine.CreateScriptSourceFromString("print 1+1", SourceCodeKind.InteractiveCode);

CompiledCode cc = ss.Compile();
cc.Execute();

int length = (int)ms.Length;
Byte[] bytes = new Byte[length];
ms.Seek(0, SeekOrigin.Begin);
ms.Read(bytes, 0, (int)ms.Length);
string result = Encoding.GetEncoding("utf-8").GetString(bytes, 0, (int)ms.Length);

Console.WriteLine(result);

将“2”打印到控制台,但是;

我希望得到1 + 1的结果,而不必打印它(因为这似乎是一个代价高昂的操作)。我将cc.Execute()的结果赋值为null。有没有其他方法可以从Execute()得到结果变量?

我也试图找到一种传递参数的方法,即结果是arg1 + arg2并且不知道如何做到这一点; Execute唯一的其他重载将ScriptScope作为参数,我以前从未使用过python。有人可以帮忙吗?

[编辑] 两个问题的答案:( Desco被接受为正确指向我)

ScriptEngine py = Python.CreateEngine();
ScriptScope pys = py.CreateScope();

ScriptSource src = py.CreateScriptSourceFromString("a+b");
CompiledCode compiled = src.Compile();

pys.SetVariable("a", 1);
pys.SetVariable("b", 1);
var result = compiled.Execute(pys);

Console.WriteLine(result);

2 个答案:

答案 0 :(得分:6)

您可以在Python中计算表达式并返回其结果(1)或将值赋给范围内的某个变量,然后选择它(2):

    var py = Python.CreateEngine();

    // 1
    var value = py.Execute("1+1");
    Console.WriteLine(value);

    // 2
    var scriptScope = py.CreateScope();
    py.Execute("a = 1 + 1", scriptScope);
    var value2 = scriptScope.GetVariable("a");
    Console.WriteLine(value2);

答案 1 :(得分:3)

你绝对不必打印它。我期待有一种只评估表达式的方法,但如果没有,那就有其他选择。

例如,在我的dynamic graphing demo我创建了一个函数,使用python:

def f(x):
    return x * x

然后从脚本范围中获取f,如下所示:

Func<double, double> function;
if (!scope.TryGetVariable<Func<double, double>>("f", out function))
{
    // Error handling here
}
double step = (maxInputX - minInputX) / 100;
for (int i = 0; i < 101; i++)
{
    values[i] = function(minInputX + step * i);
}

如果您想多次评估表达式,可以执行类似的操作,或者只需将结果分配给变量(如果您只需要对其进行一次评估)。