Создание экземпляров классов IronPython из C # - PullRequest
5 голосов
/ 04 августа 2010

Я хочу создать экземпляр класса IronPython из C #, но все мои текущие попытки кажутся неудачными.

Это мой текущий код:

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 для .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__ никогда не вызывается.

Ответы [ 3 ]

10 голосов
/ 04 августа 2010

Этот код работает с 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);
    }
}
2 голосов
/ 04 августа 2010

Я думаю, что решил свой собственный вопрос - использование класса .NET Type, похоже, отбросило информацию о типах Python.

Замена на IronPython.Runtime.Types.PythonType работает довольно хорошо.

0 голосов
/ 04 августа 2010

Похоже, вы ищете ответ, данный на этот ТАК вопрос .

...