Python 和 .Net 集成选项



我想将Python与C#集成。我发现了两种使用进程间通信和IronPython的方法

进程间通信需要在所有客户端计算机上安装 Python.exe,因此不是一个可行的解决方案。

我们开始使用IronPython,但它目前只支持2.7 python版本。我们使用的是3.7版本。

以下代码我们尝试使用IronPython:

private void BtnJsonPy_Click(object sender, EventArgs e)
{
// 1. Create Engine
var engine = Python.CreateEngine();
//2. Provide script and arguments
var script = @"C:UsersusersourcepathreposSamplePySamplePy2SamplePy2.py"; // provide full path
var source = engine.CreateScriptSourceFromFile(script);
// dummy parameters to send Python script 
int x = 3;
int y = 4;
var argv = new List<string>();
argv.Add("");
argv.Add(x.ToString());
argv.Add(y.ToString());
engine.GetSysModule().SetVariable("argv", argv);
//3. redirect output
var eIO = engine.Runtime.IO;
var errors = new MemoryStream();
eIO.SetErrorOutput(errors, Encoding.Default);
var results = new MemoryStream();
eIO.SetOutput(results, Encoding.Default);
//4. Execute script
var scope = engine.CreateScope();
var lib = new[]
{
"C:\Users\user\source\repos\SamplePy\CallingWinForms\Lib",
"C:\Users\user\source\repos\SamplePy\packages\IronPython.2.7.9\lib",
"C:\Users\user\source\repos\SamplePy\packages\IronPython.2.7.9",
"C:\Users\user\source\repos\SamplePy\packages\IronPython.StdLib.2.7.9"
//"C:\Users\user\AppData\Local\Programs\Python\Python37 - 32\Lib",
//"C:\Users\user\AppData\Local\Programs\Python\Python37-32\python.exe",
//"C:\Users\user\AppData\Local\Programs\Python\Python37 - 32",
//"C:\Users\user\AppData\Local\Programs\Python\Python37-32\DLLs"
};
engine.SetSearchPaths(lib);
engine.ExecuteFile(script, scope);
//source.Execute(scope);
//5. Display output
string str(byte[] x1) => Encoding.Default.GetString(x1);
Console.WriteLine("Errrors");
Console.WriteLine(str(errors.ToArray()));
Console.WriteLine();
Console.WriteLine("Results");
Console.WriteLine(str(results.ToArray()));
lblAns.Text = str(results.ToArray());
}

有时问题是,要进行繁重的机器学习编程,我们需要添加"模块"。这些模块将依赖于其他模块。这增加了第 4 点,执行脚本部分代码,因为必须在此处提供该模块的更多数据路径var lib = new[]并且 Iron Python 也不支持某些模块(例如有关 OCR 操作的模块等(。

由于这些限制,我发现了Pythonnet,它也有助于将.net应用程序与Python集成。但是我是新手,所以想要一些关于实现它的想法,以及可用的代码示例,以及是否可行或建议与 Python 3.7 一起使用

我检查了最初设置 Pythonnet 很麻烦,所以需要帮助或有关如何设置的步骤。还想知道未来Iron Python是否也支持Python 3.X。

我不熟悉IronPython,但我经常使用pythonnet来实现相同的目的 - 将Python与C#集成,所以我可以详细说明。

使用pythonnet的优势是拥有所有CPython软件包供您使用(numpy,scipy,pandas,Theano,Keras,scikit-learn等(,但避免了调用python的开销.exe作为单独的进程(pythonnet通过将pythonXY加载到您的进程中来工作.dll(。

请注意,pythonnet还需要独立的Python可用,但是您可以使用Embeddable Python包,该包非常轻量级,可以与您的应用程序一起分发。

pythonnnet支持 Python 3.7,但已发布的 NuGet 包仅适用于 Python 3.5。您有几种选择来获取 Python 3.7 版的 pythonnet:

  1. 从 PyPi 下载pythonnet wheel包并从中提取Python.Runtime.dll
  2. pythonnet appveyor构建项目下载NuGet包,如pythonnet安装wiki上的建议
  3. 从源代码构建

重要提示:pythonnet版本必须与您的Python版本和位数相匹配。例如,如果您使用的是Python 3.7 32 位,请下载 pythonnet-2.4.0-cp37-cp37m-win32.whl。如果你的Python 是 64 位的,请下载 pythonnet-2.4.0-cp37-cp37m-win_amd64.whl。C# 项目平台目标也必须匹配(x86 表示 32 位,x64 表示 64 位(。

使用pythonnet(在Windows 7上使用Python 3.7.4和来自最新构建工件的pythonnet NuGet测试(具有与您发布的功能类似的代码示例:

private void Test()
{
// Setup all paths before initializing Python engine
string pathToPython = @"C:UsersuserAppDataLocalProgramsPythonPython37-32";
string path = pathToPython + ";" +
Environment.GetEnvironmentVariable("PATH", EnvironmentVariableTarget.Machine);
Environment.SetEnvironmentVariable("PATH", path, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToPython, EnvironmentVariableTarget.Process);
var lib = new[]
{
@"C:UsersusersourcepathreposSamplePySamplePy2",
Path.Combine(pathToPython, "Lib"),
Path.Combine(pathToPython, "DLLs")
};
string paths = string.Join(";", lib);
Environment.SetEnvironmentVariable("PYTHONPATH", paths, EnvironmentVariableTarget.Process);
using (Py.GIL()) //Initialize the Python engine and acquire the interpreter lock
{
try
{
// import your script into the process
dynamic sampleModule = Py.Import("SamplePy");
// It is more maintainable to communicate with the script with
// function parameters and return values, than using argv 
// and input/output streams.
int x = 3;
int y = 4;
dynamic results = sampleModule.sample_func(x, y);
Console.WriteLine("Results: " + results);
}
catch (PythonException error)
{
// Communicate errors with exceptions from within python script -
// this works very nice with pythonnet.
Console.WriteLine("Error occured: ", error.Message);
}
}
}

SamplePy.py:

def sample_func(x, y):
return x*y

最新更新