4

Dynamic オブジェクトを Ironpython に引き渡そうとしていますが、Ironpython が TryInvokeMember を呼び出していないようです。代わりに、TryGetMember を呼び出し、結果を呼び出すことができないというエラーを返します。

IronPython 2.7 と 2.6.10920 で試してみました

例コード:

動的オブジェクト:

class ExampleDynamicObject: DynamicObject {
    public override bool TryGetMember(GetMemberBinder binder,
    out object result) {
        result = "TryGetMember";
        return true;
    }
    public override bool TryInvokeMember(InvokeMemberBinder binder,
    object[] args,
    out object result) {
        result = "TryInvokeMember";
        return true;
    }
}

Mathode の呼び出し

static void Main(string[] args) {
    dynamic example = new ExampleDynamicObject();
    var program = @"test = example.Call2(2)";

    var engine = Python.CreateEngine();
    var scope = engine.CreateScope();
    scope.SetVariable("example", example);
    var source = engine.CreateScriptSourceFromString(program,
    SourceCodeKind.Statements);
    source.Execute(scope);
    Console.ReadKey();
}

これにより、TryGetMember メソッドが呼び出され、Microsoft.Scripting.ArgumentTypeException "str is not callable" がスローされます。

これは、'test'(1) のようなコードを実行するとスローされます。

そのため、Python はこれが関数呼び出しであることを認識せず、代わりにプロパティを呼び出すだけのようです。

しかし、C#から呼び出そうとすると

    Console.WriteLine(example.Call);
    Console.WriteLine("----------------------------");
    Console.WriteLine(example.Call(1));

これはうまくいきます:

TryGetMember
-------------------
TryInvokeMember

これを修正する方法について誰か提案がありますか?

解決策: (編集: calledMethodeName はリストでなければなりません。そうしないと、ネストされたメソッドが機能しません)

ジェフに感謝します。

そのようなダイナミックを設計するとき:

List<string> calledMethodeNames = new List<string>();

public override bool TryGetMember(GetMemberBinder binder,
                                  out object result)
{
    calledMethodeNames.Add(binder.Name);
    result = this;
    return true;
}
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
{
    //calledMethodeNames last Element has stored the Name of the called methode (remeber to remove it)
    result = "TryInvoke";
    return true;
}

すべてが正常に機能しています。

手がかりは、オブジェクトが呼び出し可能であり、python が TryInvoke (TryInvokeMember ではない) を呼び出すよりも、オブジェクト自体をメンバーとして返すことです。

ただし、TryInvoke が呼び出されるのは、オブジェクトを返した後にオブジェクト自体が呼び出されるためです。そのため、InvokeBinder は呼び出されたメソッドの名前を知りません。だから私はそれを変数に格納します。

4

2 に答える 2

0

Python の例外 (str は呼び出し可能ではありません) に基づいて、IronPython が最初に呼び出すように見えTryGetMember、その関数が true を返すため、そのオブジェクトを使用します。

は、成功した場合にTryGetMember/TryInvokeMemberのみ返されます。trueたとえば、その意味は、パラメーターに一致するメンバーが実際に存在する場合にのみTryGetMember返されます。truebinder

更新: C#Call(2)では常にメソッド呼び出しであるため (他に考えられることは何もありません。間違っている場合はお知らせください)、C# コンパイラは を使用しますTryInvokeMethod。ただし、Pythonでは、メソッドがあればどのオブジェクトも呼び出し可能であるため、メソッドを実行するか、メンバーを取得して実行することができます。__call__Call(2)CallCall__call__

于 2013-06-14T12:04:56.360 に答える