这里提供了一种寻常的方法,在VS2017中通过C#调用Python脚本的实现,具体过程如下:
准备工作
- 安装 Python3.x 及 pip,并添加环境变量;
- 安装 Python 的 C++ 接口库:
pip install pybind11
; - 安装 Python 的包管理器 pipenv:
pip install pipenv
; - 新建一个 .NET Framework Console 项目;
- 安装 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技术站