9

これまでのところ、使用するためにPythonエンジン(IronPython)をラップする単純なクラスがあります。コードは大きく見えますが、本当に単純なので、ここにコピーして、問題をより明確にします。

コードは次のとおりです。

public class PythonInstance
{
    ScriptEngine engine;
    ScriptScope scope;
    ScriptSource source;

    public PythonInstance()
    {
        engine = Python.CreateEngine();
        scope = engine.CreateScope();
    }

    public void LoadCode(string code)
    {
        source = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Statements);
        source.Compile();
    }

    public void SetVariable(string key, dynamic variable)
    {
        scope.SetVariable(key, variable);
    }

    public void RunCode()
    {
        source.Execute(scope);
    }

    public void CallFunction(string function)
    {
        //?????? no idea what to call here
    }

}

ですから、うまく機能しますが、一度にすべてのpythonスクリプトを実行することしかできません...しかし、私がやりたいのは、pythosスクリプト内から特定の関数を呼び出せるようにすることです。

だから、私の質問:ロードされたスクリプトで特定の関数を呼び出すにはどうすればよいですか?

いくつかの情報やチュートリアルを見つけようとしていましたが、残念ながら何も見つかりませんでした。

4

2 に答える 2

12

コメントでの提案のおかげで、私はそれを使用する方法を理解することができました。これが私が今持っているものです:

public class PythonInstance
{
    private ScriptEngine engine;
    private ScriptScope scope;
    private ScriptSource source;
    private CompiledCode compiled;
    private object pythonClass;

    public PythonInstance(string code, string className = "PyClass")
    {
        //creating engine and stuff
        engine = Python.CreateEngine();
        scope = engine.CreateScope();

        //loading and compiling code
        source = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Statements);
        compiled = source.Compile();

        //now executing this code (the code should contain a class)
        compiled.Execute(scope);

        //now creating an object that could be used to access the stuff inside a python script
        pythonClass = engine.Operations.Invoke(scope.GetVariable(className));
    }

    public void SetVariable(string variable, dynamic value)
    {
        scope.SetVariable(variable, value);
    }

    public dynamic GetVariable(string variable)
    {
        return scope.GetVariable(variable);
    }

    public void CallMethod(string method, params dynamic[] arguments)
    {
        engine.Operations.InvokeMember(pythonClass, method, arguments);
    }

    public dynamic CallFunction(string method, params dynamic[] arguments)
    {
        return engine.Operations.InvokeMember(pythonClass, method, arguments);
    }

}

それをテストするには:

        PythonInstance py = new PythonInstance(@"
class PyClass:
    def __init__(self):
        pass

    def somemethod(self):
        print 'in some method'

    def isodd(self, n):
        return 1 == n % 2
");
        py.CallMethod("somemethod");
        Console.WriteLine(py.CallFunction("isodd", 6));
于 2013-01-03T14:57:15.353 に答える
4

ScriptScope.GetVariableを使用して実際の関数を取得し、それをac#関数のように呼び出すことができます。次のように使用します。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ドキュメントはありません。お役に立てれば :)

于 2018-12-04T09:42:45.847 に答える