繁体   English   中英

Python和.Net集成选项

[英]Python and .Net Integration options

我想将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:\Users\user\source\path\repos\SamplePy\SamplePy2\SamplePy2.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 Iron是否会支持Python3.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安装Wiki的建议,从pythonnet appveyor构建工件下载NuGet软件包。
  3. 从源构建

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

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

        private void Test()
        {
            // Setup all paths before initializing Python engine
            string pathToPython = @"C:\Users\user\AppData\Local\Programs\Python\Python37-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:\Users\user\source\path\repos\SamplePy\SamplePy2",
                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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM