在.NET环境中运行Python代码而不安装Python

时间:2019-06-24 20:31:18

标签: c# python .net ironpython python.net

是否可以在.NET / C#环境中生产Python代码而无需安装Python,也无需将Python代码转换为C#,即按原样部署代码?

我知道安装Python语言是合理的做法,但我的犹豫是我只是不想在生产环境中引入一种新语言并处理其测试和维护复杂性,因为我不愿意有足够的人手,他们知道Python可以解决这些问题。

我知道IronPython是基于CLR构建的,但是不知道如何在.NET中托管和维护它。它是否使人们能够将PYthon代码视为可以导入C#代码的“包”,而无需实际将Python安装为独立语言?在这种情况下,IronPython如何使我的生活更轻松? python.net可以给我更多的杠杆作用吗?

5 个答案:

答案 0 :(得分:6)

如果您不想在生产环境中引入新语言,则应保留所有代码C#,而不要引入python。

话虽如此,您无需“安装” python运行时,但您需要具有可用的运行时。如果这涉及安装nuget软件包,某些mono实现或其他方法,则您将依赖某种依赖来解释python命令。

这是一篇文章,我相信可以回答您的问题。 How to use a packed python package without installing it

答案 1 :(得分:5)

正如我在评论中提到的那样,正确而更好的方法是在您的Python代码上创建Restful服务,并从C#代码进行http请求。我不知道您对Python中的Web框架了解多少,但是有很多可以使用。为了您的需要,我建议使用Flask这是一种轻量级的微型Web框架,以创建Restful Web服务。

对于示例来说,这是非常简单的Flask网络服务:(您可以检查它的运行版本here,我将其托管在pythonOnEverywhere上)

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello from Flask!'

@app.route('/math/add/<int:num1>/<int:num2>')
def add(num1, num2):
    return '%d' % (num1+num2)

这项简单的服务,将两个数字相加并返回它们的总和。

C#代码:

using System;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

public class Program
{
    // Always use HttpClient as a singleton object
    public static HttpClient _httpClient = new HttpClient() { BaseAddress = new Uri("http://al1b.pythonanywhere.com") } ;
    public async static Task Main()
    {

        var num1 = 1;
        var num2 = 4;

        Console.WriteLine("Making http-request wait ...\r\n");      

        var mathAddResult = await _httpClient.GetAsync($"/math/add/{num1}/{num2}");

        // 200 = OK
        if(mathAddResult.StatusCode == HttpStatusCode.OK)
        {   
            Console.WriteLine(await mathAddResult.Content.ReadAsStringAsync());
        }
    }
}

输出:

Making http-request wait ... 

5

上面的代码的运行版本为now runnable on .NET Fiddle

TL; DR:

要了解和学习Flask,请查看其documentions。 (很短很不错)。我确定您将拥有复杂的Web服务,例如接受复杂或pocco对象作为Web服务输入,并返回复杂对象(如json)作为Web服务结果。

在这种情况下,您需要了解烧瓶jsonify的工作方式,此链接将告诉您how

另一方面,在C#应用程序中,您还将拥有那些复杂的对象和方案。您需要知道如何序列化,反序列化等。

Microsoft在这里的教程做得很好:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

https://docs.microsoft.com/en-us/dotnet/api/system.net.http.httpclient?view=netframework-4.8

答案 2 :(得分:5)

与使用需要Python解释器而不是.NET DLR的基于C的库运行Python相比,IronPython受限制。我想这取决于您使用Python代码的方式,如果您想使用很多第三方python库,我怀疑IronPython是否会满足您的需求。

如何构建一个完整的Python应用程序但从Docker运行它呢?

这将要求您的环境安装Docker,但随后您也可以使用Docker部署.NET应用程序,并且它们都将被隔离并且不会弄脏您的“环境”。

那里有一些基本的docker映像,它们专门用于构建Python和.NET Project以及用于运行。

答案 3 :(得分:3)

我真的不明白这个问题。您不想安装python,也不想将其引入系统,因为它具有额外的维护成本,并且您的团队缺乏有关它的基本知识。不过,您仍然想在没有任何人知道的情况下“生产”它。

我假设您想要一种脚本语言,出于某种原因,您决定使用python。我的答案就是基于这个假设。

IronPython就是为什么我们在.net世界中拥有{{1}}关键字和DLR的原因。您可以将其托管在应用程序中,并使其可以将一些python代码编译为.net兼容类型。

IronPython自己的文档中提到了它 https://ironpython.net/documentation/dotnet/dotnet.html#accessing-python-code-from-other-net-code

也有一个MSDN博客文章显示了如何做到这一点。 https://blogs.msdn.microsoft.com/seshadripv/2008/06/30/how-to-invoke-a-ironpython-function-from-c-using-the-dlr-hosting-api/

希望有帮助

答案 4 :(得分:2)

如果必须从.NET运行某些Python代码,并且不想随应用程序一起提供Python,则应使用https://cython.org/

将Python代码编译为EXE。

您可以在命令行中将变量传递给它,并通过从Python写入控制台并捕获从.NET生成的过程的输出来从Python函数接收答案。这样,它将像调用任何其他Sub或Function一样工作,唯一的区别是每个过程都是.NET的新进程。如果要来回传递复杂的对象,这可能会变得非常复杂,因为当它们在组件之间以文本形式流动时,必须将它们解开并包装。

最终,最好只在.NET中重写Python代码,而完全不走这条路。使用https://github.com/uxmal/pytocs之类的转换工具将所有Python代码转换为C#。它可能并不完美,但是它将为您提供一个代码库,以取代您要使用的Python函数。与尝试同时维护两种语言和它们之间的互操作功能相比,清理翻译过程所花费的时间更少。