从C#创建IronPython类的实例
我想在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__
方法似乎从来没有被调用过。
3 个回答
0
看起来你是在寻找对这个StackOverflow问题的回答。
2
我觉得我自己解决了问题——使用 .NET 的 Type
类似乎把 Python 的类型信息给丢掉了。
用 IronPython.Runtime.Types.PythonType
替换后效果很好。
10
这段代码适用于 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);
}
}