在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日

相关文章

  • iOS省市二级联动的数据组织PHP版

    下面是“iOS省市二级联动的数据组织PHP版”详细攻略,分以下几个部分: 1.前置知识2.数据组织3.PHP实现代码4.示例说明 1.前置知识 在进行iOS省市二级联动之前,我们需要掌握以下前置知识: PHP基础语法:包括变量、数组、循环语句等 数据库基本操作:包括增删改查操作(CRUD操作) JSON数据格式:了解JSON数据结构的基本概念及用法 2.数据…

    C# 2023年6月1日
    00
  • C#结合JavaScript实现秒杀倒计时的方法

    标题:C#结合JavaScript实现秒杀倒计时的方法 介绍: 本文主要介绍如何使用C#和JavaScript联合起来实现秒杀倒计时。在电商平台中,秒杀活动是吸引消费者的重要手段之一,而实现倒计时又是其关键所在。因此,本文将详细介绍如何实现秒杀倒计时,希望能够帮助到需要的人。 获取时间差值 在实现倒计时之前,需要获取当前时间和目标时间之间的时间差值。这可以通…

    C# 2023年6月1日
    00
  • C# TextWriter.Close – 关闭文本编写器

    C#中的TextWriter类是一个抽象类,用于向文本或流中写入字符。 Close() 方法是 TextWriter 类的一个实例方法,用于关闭当前 writer 对象并释放与此对象关联的所有系统资源(比如内存和句柄)。 以下是 TextWriter.Close 方法的使用方法: public virtual void Close (); 在调用 Close…

    C# 2023年4月19日
    00
  • ASP.NET如何定时调用WebService服务

    ASP.NET 定时调用 WebService 有多种实现方式,其中比较常用的有使用定时器 Timer 和使用 Quartz.NET 两种。下面分别给出两种方式的示例说明。 使用定时器 Timer 实现定时调用 WebService 使用 System.Windows.Forms.Timer 实现,在 WebForm 或 Windows 窗口应用程序中可以轻…

    C# 2023年6月3日
    00
  • 基于C#模拟实现回合制游戏

    基于C#模拟实现回合制游戏攻略 作为一种常见的游戏类型,回合制游戏需要玩家按照游戏设定的顺序依次操作,通常涉及到角色、武器、技能等多种元素的设计。在C#编程中,我们也可以利用面向对象思想,模拟实现一个简单的回合制游戏。 1. 定义角色类 首先我们需要定义一个角色类,包含角色的属性、技能等信息。例如: class Character{ string name;…

    C# 2023年5月15日
    00
  • C#对文件名智能排序的算法

    请听我讲解C#对文件名智能排序算法。 什么是文件名智能排序? 在计算机中,我们常常需要对文件进行排序操作。例如,我们可能通过文件名对某个文件夹中的所有文件进行排序。在Windows系统中,默认情况下,对文件名进行排序是按照每个字符的ASCII码进行排序的。这种排序方式通常不太符合人类对文件名的排序需求。因此,为了让文件名排序更符合人类的直觉,C#引入了文件名…

    C# 2023年6月1日
    00
  • C# GDI+实现时钟表盘

    C# GDI+实现时钟表盘的攻略如下: 1. 准备工作 首先需要在项目中引入System.Drawing和System.Drawing.Drawing2D命名空间,然后在代码中创建一个PictureBox控件,这个控件将用来显示时钟。 2. 绘制表盘 我们可以先创建一个空白的位图对象,然后在该对象中绘制表盘的外圆、刻度以及数字等元素。这个过程中需要使用到Gr…

    C# 2023年6月1日
    00
  • 详解c# 强制转换和类型转换

    详解C#强制转换和类型转换的完整攻略 在C#中,强制转换和类型转换是将一种类型的数据转换为另一种类型的数据的两种方法。在使用这两种方法时,我们需要了解所用的数据类型和转换方法,并注意数据转换时可能产生的精度问题。 强制转换 强制转换通常发生在两种不兼容的数据类型之间,例如将一个浮点数转换为整数。在使用强制转换时,我们需要使用强制转换运算符,例如(int)、(…

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