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

相关文章

  • C#标识符的使用小结

    我将详细讲解 “C#标识符的使用小结”: 什么是标识符? 在C#编程语言中,标识符是用来表示各种元素名称(如变量、方法、命名空间等)的一个字符序列。合法的标识符必须符合以下规则: 标识符由字母、数字或下划线(_)组成 第一个字符必须是字母或下划线 标识符不能与C#语言的关键字(如if、for等)相同 标识符区分大小写 命名规范 在使用标识符时应遵循以下规范:…

    C# 2023年5月31日
    00
  • C#存储相同键多个值的Dictionary实例详解

    下面是C#存储相同键多个值的Dictionary实例详解的完整攻略: 1. 什么是Dictionary Dictionary 是 .NET Framework 中提供的一个泛型类,它允许我们在存储和检索项目时使用键-值对。我们可以使用唯一的键来检索与其关联的值。它是线程不安全的类。 2. 什么是C#存储相同键多个值的Dictionary实例 在C#中,Dic…

    C# 2023年6月6日
    00
  • ASP.NET Identity的基本用法

    以下是“ASP.NET Identity的基本用法”的完整攻略: 什么是ASP.NET Identity ASP.NET Identity是一个用于管理用户身份和授权的框架。它提供了组API,可以轻松地将身份验证和授权功能添加到ASP.NET应用程序中。ASP.NET Identity持多种身份验证方法,包括用户名/密码、外部登录、双因素身份验证等。 ASP…

    C# 2023年5月12日
    00
  • 基于C#实现简易的键盘记录器

    基于C#实现简易的键盘记录器 简介 键盘记录器是一种记录键盘输入器的程序,它可以记录用户键盘操作的所有内容。本攻略将基于C#实现一款简易的键盘记录器。 构建步骤 1. 获取输入 键盘记录器需要获取用户键盘输入,我们可以使用System.Windows.Forms中的Keyboard来获取。 private void RecordKeystrokes() { …

    C# 2023年6月6日
    00
  • c# 字符串操作总结

    C#字符串操作总结 在C#中,字符串是一种常用的数据类型。C#提供了许多内置方法和库函数来操作和处理字符串。本篇攻略将介绍C#的常见字符串操作和用法总结。 字符串的定义 在C#中,字符串是用引号(单引号或双引号)括起来的一系列字符。例如: string str1 = "hello"; string str2 = "world&q…

    C# 2023年5月15日
    00
  • ASP.NET MVC使用typeahead.js实现输入智能提示功能

    当我们需要在 ASP.NET MVC 应用程序中实现输入智能提示功能时,可以使用 typeahead.js 插件。typeahead.js 可以根据用户输入的字符,从服务器获取匹配的建议列表,并输入框下方显示这些建议。以下是详细的攻略: 步骤1:装 typeahead.js 在 Visual Studio 中打开项目,键单击项目名称,选择“管理 NuGet …

    C# 2023年5月12日
    00
  • C#实现根据图片的链接地址获取图片的后缀名

    当我们给很多图片命名时,我们通常会使用图片的结尾部分作为图片的后缀名。因此,获取图片的后缀名是一项非常常见的任务。在C#中,我们可以通过一定的代码实现获取图片的后缀名。 首先,我们需要明确一下目标:根据图片的链接地址获取图片的后缀名。这个目标可以分解为以下几个步骤: 从链接地址中获取图片的文件名; 将文件名转换成小写形式; 从文件名中获取后缀名。 以下是详细…

    C# 2023年6月1日
    00
  • C#基本语法简介

    以下是关于C#基本语法的简介: C#基本语法 数据类型 C#中有许多数据类型,包括整数(int、long)、浮点数(float、double)、字符(char)、布尔值(bool)等等。同时,C#也支持用户自定义数据类型,使用关键字“class”进行定义。 以下是数据类型示例: int age = 18; float price = 9.99f; char …

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