Reputation:
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.
Upvotes: 6
Views: 5498
Reputation: 16782
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);
}
}
Upvotes: 10
Reputation:
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.
Upvotes: 2
Reputation: 881477
Looks like you're looking for the answer given to this SO question.
Upvotes: 0