将列表从 IronPython 传递到 C#(二)
Passing lists from IronPython to C# (2)
已经有一个类似的回答问题in this post
但是这个是不同的:我实际上没有从 Func<IList<double>> get_a_list = pyOps.GetMember<Func<IList<double>>>(class1, "get_a_list");
这样的调用中得到 IronPython.Runtime.List
(我确实使用了 System.Linq
;),其中 get_a_list
是 Python 代码表示 returns 一个 Python [] 列表。我得到一个 {IronPython.Runtime.ListGenericWrapper<double>}
。如何将其转换为 C# 列表?
请参阅下面的代码 - 除了将 x
变量导入 C# 之外,一切正常。
class class1(object):
"""Support demo of how to call python from C#"""
def __init__(self):
self.a = 5
def get_a_square(self):
return pow(self.a,2)
def get_a_times_b(self, b):
return self.a*b
def get_a_list(self):
return [self.a,self.a,self.a]
并且 C# 代码是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using System.Reflection;
using System.IO;
namespace DemoUsingPythonModule
{
class Program
{
static void Main(string[] args)
{
ScriptEngine pyEngine = Python.CreateEngine();
// Load the DLL and the Python module
Assembly dpma = Asse mbly.LoadFile(Path.GetFullPath("DemoPythonModule.dll"));
pyEngine.Runtime.LoadAssembly(dpma);
ScriptScope pyScope = pyEngine.Runtime.ImportModule("class1");
ObjectOperations pyOps = pyEngine.Operations;
// Instantiate the Python Class
var classObj = pyScope.GetVariable("class1");
object class1 = pyOps.Invoke(classObj);
// Invoke a method of the class
var a2 = pyOps.InvokeMember(class1, "get_a_square", new object[0]);
Console.Write(a2.ToString()+'\n');
// create a callable function to 'get_a_square'
Func<double> get_a_square = pyOps.GetMember<Func<double>>(class1, "get_a_square");
double a2_2 = get_a_square();
// create a callable function to 'get_a_times_b'
Func<double, double> get_a_times_b = pyOps.GetMem ber<Func<double, double>>(class1, "get_a_times_b");
Console.WriteLine(get_a_times_b(3.0).ToString());
Console.WriteLine(get_a_times_b(4.0).ToString());
Func<IList<double>> get_a_list = pyOps.GetMember<Func<IList<double>>>(class1, "get_a_list");
var x = get_a_list();
Console.WriteLine(x.Cast<double>().ToList().ToString());
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
好的,我找到了。类型确实是 IronPython.Runtime.ListGenericWrapper<double>
但上面的 Python 代码 returns 是一个整数列表。如果我将构造函数更改为 self.a = 5.0
,事情就会起作用。
已经有一个类似的回答问题in this post
但是这个是不同的:我实际上没有从 Func<IList<double>> get_a_list = pyOps.GetMember<Func<IList<double>>>(class1, "get_a_list");
这样的调用中得到 IronPython.Runtime.List
(我确实使用了 System.Linq
;),其中 get_a_list
是 Python 代码表示 returns 一个 Python [] 列表。我得到一个 {IronPython.Runtime.ListGenericWrapper<double>}
。如何将其转换为 C# 列表?
请参阅下面的代码 - 除了将 x
变量导入 C# 之外,一切正常。
class class1(object):
"""Support demo of how to call python from C#"""
def __init__(self):
self.a = 5
def get_a_square(self):
return pow(self.a,2)
def get_a_times_b(self, b):
return self.a*b
def get_a_list(self):
return [self.a,self.a,self.a]
并且 C# 代码是
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using System.Reflection;
using System.IO;
namespace DemoUsingPythonModule
{
class Program
{
static void Main(string[] args)
{
ScriptEngine pyEngine = Python.CreateEngine();
// Load the DLL and the Python module
Assembly dpma = Asse mbly.LoadFile(Path.GetFullPath("DemoPythonModule.dll"));
pyEngine.Runtime.LoadAssembly(dpma);
ScriptScope pyScope = pyEngine.Runtime.ImportModule("class1");
ObjectOperations pyOps = pyEngine.Operations;
// Instantiate the Python Class
var classObj = pyScope.GetVariable("class1");
object class1 = pyOps.Invoke(classObj);
// Invoke a method of the class
var a2 = pyOps.InvokeMember(class1, "get_a_square", new object[0]);
Console.Write(a2.ToString()+'\n');
// create a callable function to 'get_a_square'
Func<double> get_a_square = pyOps.GetMember<Func<double>>(class1, "get_a_square");
double a2_2 = get_a_square();
// create a callable function to 'get_a_times_b'
Func<double, double> get_a_times_b = pyOps.GetMem ber<Func<double, double>>(class1, "get_a_times_b");
Console.WriteLine(get_a_times_b(3.0).ToString());
Console.WriteLine(get_a_times_b(4.0).ToString());
Func<IList<double>> get_a_list = pyOps.GetMember<Func<IList<double>>>(class1, "get_a_list");
var x = get_a_list();
Console.WriteLine(x.Cast<double>().ToList().ToString());
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
}
}
好的,我找到了。类型确实是 IronPython.Runtime.ListGenericWrapper<double>
但上面的 Python 代码 returns 是一个整数列表。如果我将构造函数更改为 self.a = 5.0
,事情就会起作用。