在VS2017中用C#调用python脚本的实现

这里提供了一种寻常的方法,在VS2017中通过C#调用Python脚本的实现,具体过程如下:

准备工作

  1. 安装 Python3.x 及 pip,并添加环境变量;
  2. 安装 Python 的 C++ 接口库:pip install pybind11
  3. 安装 Python 的包管理器 pipenv:pip install pipenv
  4. 新建一个 .NET Framework Console 项目;
  5. 安装 NuGet 包:Microsoft.Python.Core 和 Microsoft.Python.Core.Interpreter;

调用 Python 脚本

C#调用Python脚本需要用到的方法:completeSetup,runPython,shutdownPython。具体执行逻辑请看下面代码:

using Microsoft.Python.Core;
using Microsoft.Python.Core.OS;
using Microsoft.Python.Core.Services;
using Microsoft.Python.Tools.Interpreter;

using static Microsoft.Python.Core.DisposableHelpers;

private IPythonInterpreter _interpreter;
private IServiceManager _services;

public void completeSetup()
{
    var os = new Platform(OS.PlatformKind);
    _services = new ServiceManager();
    _services.AddService(new SystemModule(_services));
    _services.AddService(new OsModule(os, _services));
    _services.AddService(new SysModule(_services));
    _services.AddService(new ArgvModule(new[] { "app" }, _services));
    _services.AddService(new BuiltinModule(_services));
    _services.AddService(new BuiltinImporter(_services));
    _services.AddService(new AstPythonInterpreterFactory(_services));
    _services.AddService(new AstPythonInterpreterSettings(_services));
}

public void runPython(string pyCode)
{
    var script = _interpreter.CreateScriptSourceFromString(pyCode);
    script.Execute();
}

public void shutdownPython()
{
    _interpreter = null;
    _services.Dispose();
    _services = null;
}

public void init()
{
    completeSetup();
    var factory = new AstPythonInterpreterFactory(_services);
    var options = new InterpreterConfiguration
    {
        InterpreterPath = @"yourPythonPath",
        LibraryPath = PythonPaths.Python35.Libraries.PythonLibrary,
        UseDefaultDatabase = true,
        DatabasePath = PythonPaths.GetCachedDatabasePath(factory.Configuration, factory.GetCacheFolderPath())
    };
    _interpreter = factory.CreateInterpreter(options);
}

代码的执行流程:首先在init方法中初始化Python环境,这个和Python的交互操作似乎也可以用到。completeSetup方法用来整合该项目使用的Python包,runPython函数用于执行Python代码,shutdownPython用于应用程序关闭时关闭Python环境。

另外,还有一个 IPythonModuleManager 接口和无法应用上下文的对象,因此必须手动添加包:

_services.AddService(new PythonPackageManager(new PipPackageManager(_services), _services));
_services.AddService(new AstPythonModuleManagement(_services, null));

其中第二个参数传 null,Python的上下文暂时不考虑。

示例一

使用Python脚本进行图像处理。例如,Python脚本如下:

from PIL import Image

def doSomething():
    img1 = Image.open("one.jpg")
    img2 = Image.open("two.jpg")
    img1_size = img1.size
    img2_size = img2.size
    joint_height = img1_size[1] + img2_size[1]
    joint_width = max(img1_size[0], img2_size[0])
    joint_image = Image.new('RGB', (joint_width, joint_height))
    joint_image.paste(img1, (0, 0))
    joint_image.paste(img2, (0, img1_size[1]))
    joint_image.save("image.jpg")

doSomething()

那么,如何在C#中调用Python代码里面的 doSomething 呢?使用我们先前完成的 PythonRunner,调用函数即可:

init();

string pythonScript = @"from PIL import Image
def doSomething():
    img1 = Image.open(""one.jpg"")
    img2 = Image.open(""two.jpg"")
    img1_size = img1.size
    img2_size = img2.size
    joint_height = img1_size[1] + img2_size[1]
    joint_width = max(img1_size[0], img2_size[0])
    joint_image = Image.new('RGB', (joint_width, joint_height))
    joint_image.paste(img1, (0, 0))
    joint_image.paste(img2, (0, img1_size[1]))
    joint_image.save(""image.jpg"")

doSomething()";

runPython(pythonScript);

shutdownPython();

直接调用 doSomething() 方法。

然后,我们把 one.jpg 和 two.jpg 放在项目文件中,并编译运行程序,可以在项目目录下找到 image.jpg 图片。

示例二

使用Python脚本进行爬虫,例如:

from urllib import request
import chardet

def getHTMLText(url):
    headers = {'User-Agent':'Mozilla/5.0'}
    req = request.Request(url,headers=headers)
    response = request.urlopen(req)
    html = response.read()
    html = html.decode(chardet.detect(html)['encoding'])  
    return html

def doSomething():
    url = "https://movie.douban.com/cinema/nowplaying/beijing/"
    html = getHTMLText(url)
    print(html[:1000])

doSomething()

那么,在C#中调用 doSomething 方法的代码如下:

init();

string pythonScript = @"from urllib import request
import chardet

def getHTMLText(url):
    headers = {'User-Agent':'Mozilla/5.0'}
    req = request.Request(url,headers=headers)
    response = request.urlopen(req)
    html = response.read()
    html = html.decode(chardet.detect(html)['encoding'])  
    return html

def doSomething():
    url = ""https://movie.douban.com/cinema/nowplaying/beijing/""
    html = getHTMLText(url)
    print(html[:1000])

doSomething()";

runPython(pythonScript);

shutdownPython();

运行程序可以看到 C# 输出的 Python 脚本执行结果。

总的来说,通过在 VS2017 中使用 C# 调用 Python 脚本的方法是比较简单的,而且这种方法可以用于在两种不同编程语言之间建立桥梁,让它们之间相互调用。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:在VS2017中用C#调用python脚本的实现 - Python技术站

(0)
上一篇 2023年5月15日
下一篇 2023年5月15日

相关文章

  • 记一次 Windows10 内存压缩模块 崩溃分析

    一:背景 1. 讲故事 在给各位朋友免费分析 .NET程序 各种故障的同时,往往也会收到各种其他类型的dump,比如:Windows 崩溃,C++ 崩溃,Mono 崩溃,真的是啥都有,由于基础知识的相对缺乏,分析起来并不是那么的顺利,今天就聊一个 Windows 崩溃的内核dump 吧,这个 dump 是前几天有位朋友给到我的,让我帮忙看一下,有了dump之…

    C# 2023年5月2日
    00
  • jQuery uploadify在谷歌和火狐浏览器上传失败的解决方案

    下面是详细讲解“jQueryuploadify在谷歌和火狐浏览器上传失败的解决方案”的完整攻略。 问题描述 在使用jQueryuploadify进行图片上传的过程中,在谷歌和火狐浏览器上会出现上传失败的情况,具体表现为无法选择上传文件和上传进度条不显示等问题。 解决方案 1. 修改uploadify.js文件中的swf文件路径 修改uploadify.js文…

    C# 2023年5月15日
    00
  • C# WinForm国际化实现的简单方法

    那么下面我来详细讲解一下“C# WinForm国际化实现的简单方法”。 什么是国际化 国际化(Internationalization),简称I18N,指将软件(尤其是在开发过程中)设计成可同时支持多种语言和字符集的技术。通俗点说,国际化就是将我们的程序在不同地区、不同语言下也能够顺利运行,显示相应的语言文本和界面信息。 WinForm国际化实现的简单方法 …

    C# 2023年6月6日
    00
  • C# 设置Chart的X轴为时间轴​​​​​​​详情

    下面是关于C#设置Chart的X轴为时间轴的完整攻略: 步骤一:添加 NuGet 包 在 Visual Studio 中打开相应的项目,右键单击项目并选择“管理 NuGet 包”。在 NuGet 界面的搜索栏中输入“System.Windows.Forms.DataVisualization”,选择“System.Windows.Forms.DataVisu…

    C# 2023年6月1日
    00
  • C#实现单例模式的几种方法总结

    C#实现单例模式的几种方法总结 单例模式是一种常用的设计模式,它确保一个类只有一个实例,而且提供一个访问该实例的全局访问点。在C#中,实现单例模式有多种方法,下面将详细讲解。 1. 懒汉式单例模式 在懒汉式单例模式中,实例对象在第一次被访问时才会被创建。它的实现方式比较简单,如下所示: public class Singleton { private sta…

    C# 2023年5月15日
    00
  • C#入门之结构类型Struct

    C#入门之结构类型Struct 简介 Struct是C#中的一种结构类型,也称为值类型(Value Type),与类(Class)类型相对。Struct可以存储少量相关联的数据,常用于定义简单的数据类型,如好友列表、地址等。 与Class不同的是,Struct在创建时是值类型在栈中创建的,而Class是引用类型在堆中创建的。因此,Struct使用起来较为高效…

    C# 2023年6月7日
    00
  • C# FTP,GetResponse(),远程服务器返回错误

    问题:一个C#程序需要连接FTP服务器,但在使用GetResponse()方法时,接收到了远程FTP服务器返回的错误信息,如何解决此问题? 解决方法:1. 获取错误的详细信息在C#程序中,我们可以使用GetResponse()方法来获取FTP服务器的响应,但如果在获取响应的过程中出现错误,会导致程序抛出WebException异常。为了正确获取FTP服务器的…

    C# 2023年5月15日
    00
  • C# dataset存放多张表的实例

    下面是详细的“C# dataset存放多张表的实例”攻略: 1. 创建dataset实例 在使用dataset存放多张表之前,需要创建一个dataset的实例,代码如下: DataSet ds = new DataSet(); 2. 创建多张表 在创建了dataset实例之后,需要在其中创建多张表。代码如下: DataTable dt1 = new Data…

    C# 2023年5月31日
    00
合作推广
合作推广
分享本页
返回顶部