从 C# 创建 IronPython 类的实例

发布于 2024-09-12 22:55:30 字数 1200 浏览 0 评论 0原文

我想从 C# 创建 IronPython 类的实例,但我当前的尝试似乎都失败了。

这是我当前的代码:

ConstructorInfo[] ci = type.GetConstructors();

foreach (ConstructorInfo t in from t in ci
                              where t.GetParameters().Length == 1
                              select t)
{
    PythonType pytype = DynamicHelpers.GetPythonTypeFromType(type);
    object[] consparams = new object[1];
    consparams[0] = pytype;
    _objects[type] = t.Invoke(consparams);
    pytype.__init__(_objects[type]);
    break;
}

我能够通过调用 t.Invoke(consparams) 获取创建的对象实例,但 __init__ 方法似乎没有被调用,因此所有属性我从 Python 脚本中设置的内容未被使用。即使使用显式的 pytype.__init__ 调用,构造的对象似乎仍然没有被初始化。

使用 ScriptEngine.Operations.CreateInstance 似乎也不起作用。

我正在使用 .NET 4.0 和 IronPython 2.6 for .NET 4.0。

编辑:关于我打算如何执行此操作的小澄清:

在 C# 中,我有一个类如下:

public static class Foo
{
    public static object Instantiate(Type type)
    {
        // do the instantiation here
    }
}

在 Python 中,以下代码:

class MyClass(object):
    def __init__(self):
        print "this should be called"

Foo.Instantiate(MyClass)

__init__ 方法从不似乎被称为。

I want to create an instance of an IronPython class from C#, but my current attempts all seem to have failed.

This is my current code:

ConstructorInfo[] ci = type.GetConstructors();

foreach (ConstructorInfo t in from t in ci
                              where t.GetParameters().Length == 1
                              select t)
{
    PythonType pytype = DynamicHelpers.GetPythonTypeFromType(type);
    object[] consparams = new object[1];
    consparams[0] = pytype;
    _objects[type] = t.Invoke(consparams);
    pytype.__init__(_objects[type]);
    break;
}

I am able to get the created instance of the object from calling t.Invoke(consparams), but the __init__ method doesn't seem to be called, and thus all the properties that I set from my Python script aren't used. Even with the explicit pytype.__init__ call, the constructed object still doesn't seem to be initialised.

Using ScriptEngine.Operations.CreateInstance doesn't seem to work, either.

I'm using .NET 4.0 with IronPython 2.6 for .NET 4.0.

EDIT: Small clarification on how I'm intending to do this:

In C#, I have a class as follows:

public static class Foo
{
    public static object Instantiate(Type type)
    {
        // do the instantiation here
    }
}

And in Python, the following code:

class MyClass(object):
    def __init__(self):
        print "this should be called"

Foo.Instantiate(MyClass)

The __init__ method never seems to be called.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

方觉久 2024-09-19 22:55:30

此代码适用于 IronPython 2.6.1

    static void Main(string[] args)
    {
        const string script = @"
class A(object) :
    def __init__(self) :
        self.a = 100

class B(object) : 
    def __init__(self, a, v) : 
        self.a = a
        self.v = v
    def run(self) :
        return self.a.a + self.v
";

        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();
        engine.Execute(script, scope);

        var typeA = scope.GetVariable("A");
        var typeB = scope.GetVariable("B");
        var a = engine.Operations.CreateInstance(typeA); 
        var b = engine.Operations.CreateInstance(typeB, a, 20);
        Console.WriteLine(b.run()); // 120
    }

根据澄清的问题进行编辑

    class Program
    {
        static void Main(string[] args)
        {
            var engine = Python.CreateEngine();
            var scriptScope = engine.CreateScope();

            var foo = new Foo(engine);

            scriptScope.SetVariable("Foo", foo);
            const string script = @"
class MyClass(object):
    def __init__(self):
        print ""this should be called""

Foo.Create(MyClass)
";
            var v = engine.Execute(script, scriptScope);
        }
    }

public  class Foo
{
    private readonly ScriptEngine engine;

    public Foo(ScriptEngine engine)
    {
        this.engine = engine;
    }

    public  object Create(object t)
    {
        return engine.Operations.CreateInstance(t);
    }
}

This code works with IronPython 2.6.1

    static void Main(string[] args)
    {
        const string script = @"
class A(object) :
    def __init__(self) :
        self.a = 100

class B(object) : 
    def __init__(self, a, v) : 
        self.a = a
        self.v = v
    def run(self) :
        return self.a.a + self.v
";

        var engine = Python.CreateEngine();
        var scope = engine.CreateScope();
        engine.Execute(script, scope);

        var typeA = scope.GetVariable("A");
        var typeB = scope.GetVariable("B");
        var a = engine.Operations.CreateInstance(typeA); 
        var b = engine.Operations.CreateInstance(typeB, a, 20);
        Console.WriteLine(b.run()); // 120
    }

EDITED according to clarified question

    class Program
    {
        static void Main(string[] args)
        {
            var engine = Python.CreateEngine();
            var scriptScope = engine.CreateScope();

            var foo = new Foo(engine);

            scriptScope.SetVariable("Foo", foo);
            const string script = @"
class MyClass(object):
    def __init__(self):
        print ""this should be called""

Foo.Create(MyClass)
";
            var v = engine.Execute(script, scriptScope);
        }
    }

public  class Foo
{
    private readonly ScriptEngine engine;

    public Foo(ScriptEngine engine)
    {
        this.engine = engine;
    }

    public  object Create(object t)
    {
        return engine.Operations.CreateInstance(t);
    }
}
岁月苍老的讽刺 2024-09-19 22:55:30

我想我解决了我自己的问题——使用 .NET Type 类似乎已经丢弃了 Python 类型信息。

将其替换为 IronPython.Runtime.Types.PythonType 效果非常好。

I think I solved my own question -- using the .NET Type class seems to have discarded Python type information.

Replacing it with IronPython.Runtime.Types.PythonType works quite well.

衣神在巴黎 2024-09-19 22:55:30

看起来您正在寻找这个问题的答案。

Looks like you're looking for the answer given to this SO question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文