介绍

在 C# 程序中嵌入 IronPython 得到了很好的支持。在本教程中,我们将展示如何完成这个项目。

首先,我们将展示两个非常基本的例子,说明如何执行一个不导入任何模块的非常简单的脚本。然后,再展示如何执行使用模块的脚本。

在 C# 中执行 Python

第一个例子

我们来创建一个执行Python脚本的 C# 应用​​程序的简单例子。我们使用 Visual Studio 2017 C# 控制台应用程序模板创建一个新项目。我们称之为PythonScriptExecution1。完整的例子可以从我们的GitHub仓库获得:IronPythonTutorials / CSharpIntegration / PythonScriptExecution1。

项目创建完成后,我们使用 NuGet 包管理器添加 IronPython 包,将其安装到当前项目中。这会将以下程序集添加到项目中:

IronPython

IronPython.Model

IronPython.SQLite

IronPython.Wpf

Microsoft.Dynamic

Microsoft.Scripting

Microsoft.Scripting.AspNet

Microsoft.Scripting.Metadata

对于第一个例子,我们调用一个 Python 脚本,它将简单地打印出 “Hello World!”。在控制台上。为了保持它尽可能简单,我们只需将 Python 代码硬编码到一个字符串中,然后使用 CreateScriptSourceFromString 从中创建 Microsoft.Scripting.Hosting.ScriptSource 实例。正如你所看到的,这很容易做,只需要3行代码。

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

var pythonScripts = pythonEngin.CreateScriptSourceFromString("print'hello world'");

pythonScripts.Execute();

}

控制台输出

hello world

第二个例子

第二个例子与第一个例子几乎相同,但是我们将使用 CreateScriptSourceFromFile 函数从文件中加载脚本,而不是将其硬编码到一个字符串中。由于我们将脚本放在与 Program.cs 文件相同的目录中,我们需要当从 Visual Studio 执行程序时,会出现两个目录。这就是为什么我们脚本的路径是.. \ .. \ HelloWorld.py。您当然可以将脚本放在与可执行文件相同的目录中。代码如下所示。执行程序时,输出当然与前面的示例相同。

完整的例子可以从我们的GitHub仓库获得:IronPythonTutorials/CSharpIntegration/PythonScriptExecution2。

print('Hello World')

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

var pythonScripts = pythonEngin.CreateScriptSourceFromFile("..\\.\\HelloWorld.py"));

pythonScripts.Execute();

Console.ReadKey();

}

搜索路径

通常,Python 脚本将依赖于某个模块,或者是一个自定义模块或 Python 标准库中的模块。我们将展示如何使用标准库,但是考虑到大量的模块,我们将从一个更基本的例子开始。

处理模块的唯一困难是设置引擎将查找模块的路径列表。该ScriptEngine的类提供了一个函数来检索的搜索路径当前列表:GetSearchPaths,另一个设置列表:SetSearchPaths。SetSearchPaths 替换现有的列表,所以如果你想添加一个搜索路径,你将需要首先获取当前列表,添加新的路径,然后将更新的列表传递给 SetSearchPaths 函数。

我们来举例说明一个简单的例子。我们修改之前的的一个示例,以便在 HelloWorld.py 导入另一个名为 HelloWorldModule.py 的模块。我们把这两个文件放在与Program.cs相同的目录下。这两个文件的来源如下所示。

完整的例子可以从我们的GitHub仓库获得:IronPythonTutorials/CSharpIntegration/PythonScriptExecution3。

HelloWorldModule.py

def PrintHelloWorld():

print("Hello World")

HelloWorld.py

import HelloWorldModule

HelloWorldModule.PrintHelloWorld()

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

Console.WriteLine("Search Paths:");

var searchPaths = pythonEngin.GetSearchPaths();

foreach (var item in searchPaths)

{

Console.WriteLine(item);

}

Console.WriteLine();

searchPaths.Add("..\\..");

pythonEngin.SetSearchPaths(searchPaths);

var pythonScript = pythonEngin.CreateScriptSourceFromFile("..\\..\\HelloWorld.py");

pythonScript.Execute();

}

显然,这是一个稍微做作的例子,因为你通常会把脚本放在一个更合理的位置,但是你应该明白这个想法。

如果一切正常,你应该得到以下输出。

Search Paths:

.

C:\Users\hippieZhou\Documents\Projects\IronPythonTutorials\03_PythonScriptExecution3\bin\Debug\Lib

C:\Users\hippieZhou\Documents\Projects\IronPythonTutorials\03_PythonScriptExecution3\bin\Debug\DLLs

Hello World

但是,如果由于某种原因无法找到一个模块,你会得到下面的异常抛出。

Unhandled Exception: IronPython.Runtime.Exceptions.ImportException: No module na

med os

at Microsoft.Scripting.Runtime.LightExceptions.CheckAndThrow(Object value)

at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame

frame)

at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)

at Microsoft.Scripting.Interpreter.LightLambda.Run1[T0,TRet](T0 arg0)

at IronPython.Compiler.RuntimeScriptCode.InvokeTarget(Scope scope)

at IronPython.Compiler.RuntimeScriptCode.Run()

at Microsoft.Scripting.Hosting.ScriptSource.Execute()

at PythonScriptExecution3.Program.Main(String[] args) in c:\p4client2\Tutoria

ls\Development\IronPython\Examples\CSharpIntegration\PythonScriptExecution3\Pyth

onScriptExecution3\Program.cs:line 16

让我们仔细看一下搜索路径的初始列表。

默认情况下,当前工作目录将包含在搜索路径列表中。但是,如果您依赖于此,您的应用程序将会工作与否,具体取决于用户启动应用程序时当前的工作目录。在默认情况下,IronPython 将在搜索路径中包含两条与应用程序本身安装位置相关的路径:在上面的输出中可以看到的Lib和DLL路径。这些位置是将模块与主应用程序保持在一起的好选择。

IronPython 实现使用 Assembly.GetEntryAssembly() 函数来获取主机的路径,以便添加 “Lib” 和 “DLL” 路径。有些情况下,Assembly.GetEntryAssembly()将返回 null,这些路径将不会被添加。一个这样的情况是,当环境是 ASP.NET。

标准库

在您的应用程序中使用标准库并不困难。包含标准库的单独的NuGet包可用。这个包将所有的标准库模块添加到 Visual Studio 项目中。出现的问题是,应用程序使用的模块需要与它分发。如何做到这一点取决于具体情况。在最简单的情况下,您可以将所需的模块放在与应用程序二进制文件相同的目录中,并将它们一起分发。如果您选择该解决方案,则默认搜索路径应该足够,因为它包含“。” 目录。

现在让我们来看一个使用标准库的脚本的简单例子。完整的例子可以从我们的 GitHub 仓库获得:IronPythonTutorials/CSharpIntegration/PythonScriptExecution4。

使用 NuGet 获取 IronPython 标准库:IronPython.StdLib

HelloWorldBase64.py

import base64

originalString = b"Hello World!"

print("OriginalString:" + str(originalString))

encodedString = base64.b64encode(originalString)

print("EncodedString:" + str(encodedString))

decodedString = base64.b64decode(encodedString);

print("Decoded String:" + str(decodedString))

C#

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

Console.WriteLine("Search paths:");

var searchPaths = pythonEngin.GetSearchPaths();

foreach (var path in searchPaths)

{

Console.WriteLine(path);

}

Console.WriteLine();

searchPaths.Add("..\\..\\Lib");

pythonEngin.SetSearchPaths(searchPaths);

var pythonScript = pythonEngin.CreateScriptSourceFromFile("..\\..\\HelloWorldBase64.py");

pythonScript.Execute();

}

输出

Search paths:

.

C:\Users\hippieZhou\Documents\Projects\IronPythonTutorials\04_PythonScriptExecution4\bin\Debug\Lib

C:\Users\hippieZhou\Documents\Projects\IronPythonTutorials\04_PythonScriptExecution4\bin\Debug\DLLs

OriginalString:Hello World!

EncodedString:SGVsbG8gV29ybGQh

Decoded String:Hello World!

共享变量

在 Microsoft.Scripting.Hosting.ScriptScope 类用于保存的是当前在范围内的变量及其关联值列表。本 ScriptScope 类提供的方法来设置,获取和范围删除变量。他们是 SetVariable, GetVariable 和 RemoveVariable。要获取范围中所有变量的列表,请使用GetVariableNames 方法。

在我们最开始的例子中,我们使用 pythonScript.Execute(); 来运行脚本。无参数 Execute() 函数在 ScriptScope 内部创建实例,因此调用者无法访问它。但是,我们可以使用其他重载来创建 ScriptScope 自己并将其传递给 Execute() 函数。

以下示例显示了如何使用这些函数。完整的例子可以从我们的GitHub仓库获得:IronPythonTutorials/CSharpIntegration/PythonScriptExecution5。

Program.cs

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

var pythonScript = pythonEngin.CreateScriptSourceFromString(

"helloWorldString='Hello World!'\n" +

"print(helloWorldString) \n" +

"print(extrnalString)");

var scope = pythonEngin.CreateScope();

scope.SetVariable("extrnalString", "How are you.");

pythonScript.Execute(scope);

Console.WriteLine();

Console.WriteLine("List of variables in the scope:");

foreach (var name in scope.GetVariableNames())

{

Console.Write(name+ " ");

}

Console.WriteLine();

Console.WriteLine("Variable values:");

Console.WriteLine("helloWorldString:" + scope.GetVariable("helloWorldString"));

Console.WriteLine("extrnalString:" + scope.GetVariable("extrnalString"));

Console.ReadKey();

}

输出

Hello World!

How are you.

List of variables in the scope:

extrnalString __builtins__ __file__ __name__ __doc__ helloWorldString

Variable values:

helloWorldString:Hello World!

extrnalString:How are you.

在这个例子中,脚本定义了这个 helloWorldString 变量,并使用了一个 externalString 在脚本中没有定义的变量 。然后打印这两个变量。

该 externalString 变量显示了C# 代码如何使用该 SetVariable 方法将变量添加到脚本可以使用的范围。

脚本执行后,范围包含由脚本添加的变量列表。C# 代码使用我们前面提到的各种函数来打印执行后的范围内的内容。

导入模块

在本教程前面,我们看到了 Python 脚本如何使用 Python import 语句,只要搜索路径设置正确,就可以像任何常规的 Python 脚本一样使用Python 语句。在这里我们提出另一个有趣的方法,即从 C# 代码中导入模块,而不是 Python 代码。

静态 IronPython.Hosting.Python.ImportModule 函数可以用来导入一个模块。它返回 ScriptScope 包含导入模块中所有变量的类的一个实例。该 ScriptScope 在上面有解释。例如,您可以使用返回的作用域并将其传递给 ScriptSource.Execute 函数,以执行另一个可以使用导入模块的功能的 Python 脚本,甚至可以使用它直接从 C# 执行 Python 方法,如下面的示例所示。

将 ImportModule 搜索路径中的模块作为 Python import 语句进行查找将会这样做,重要的是正确设置路径或找不到模块。

以下示例显示了如何在 Python 模块中定义的函数可以像 C# 函数一样执行。

HelloWorldModule.py

def PrintHelloWorld():

print("Hello World!")

def PrintMessage(message):

print(message)

def Add(arg1,arg2):

return (arg1 + arg2)

Program.cs

static void Main(string[] args)

{

var pythonEngin = IronPython.Hosting.Python.CreateEngine();

var searchPaths = pythonEngin.GetSearchPaths();

searchPaths.Add("..\\..");

pythonEngin.SetSearchPaths(searchPaths);

var scope = IronPython.Hosting.Python.ImportModule(pythonEngin, "HelloWorldModule");

dynamic printHelloWorldFunction = scope.GetVariable("PrintHelloWorld");

printHelloWorldFunction();

dynamic printMessageFunction = scope.GetVariable("PrintMessage");

printMessageFunction("GoodBye!");

dynamic addFunction = scope.GetVariable("Add");

Console.WriteLine("The sum of 1 and 2 is " + addFunction(1,2));

Console.ReadKey();

}

总结

官网给的示例教程是 Visual Studio 2013 + python 2.x 版本的,对于 Visual Studio 2017 + Python 3.X 版本的使用方式影响不大。按照官网描述一步一步还是可以完成整个的基本教程。

个人理解:IronPython 其实就是相当于将 Python 编译成字节码,然后通过 IronPython 创建的虚拟 Python 运行环境(类似虚拟机)从而达到能够运行 Python 的目的。经过个人(不科学的)测试,这种模式的运行效率并不是很高,在 Python 慢的基础上还要慢一个节拍。所以,想在生产环境中使用的话需要慎重考虑。

参考

ironpython console_IronPython初体验相关推荐

  1. 苹果电脑安装python3密码_mac系统安装Python3初体验

    前沿 对于iOS开发不要随便拆卸系统自带的Python,因为有很多 library 还是使用 Python2.7. 1 安装Xcode 1.1 App Store 搜索Xcode 并安装 1.2 安装 ...

  2. MapReduce编程初体验

    需求:在给定的文本文件中统计输出每一个单词出现的总次数 第一步: 准备一个aaa.txt文本文档 第二步: 在文本文档中随便写入一些测试数据,这里我写入的是 hello,world,hadoop he ...

  3. 小程序 缩放_缩放流星应用程序的初体验

    小程序 缩放 by Elie Steinbock 埃莉·斯坦博克(Elie Steinbock) 缩放流星应用程序的初体验 (First Experiences Scaling a Meteor Ap ...

  4. wxWidgets刚開始学习的人导引(3)——wxWidgets应用程序初体验

    wxWidgets刚開始学习的人导引全文件夹   PDF版及附件下载 1 前言 2 下载.安装wxWidgets 3 wxWidgets应用程序初体验 4 wxWidgets学习资料及利用方法指导 5 ...

  5. 用鸿蒙跑了个 “hello world”!鸿蒙开发初体验

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 来源 | https://my.oschina.net/u ...

  6. Windows Embedded Standard开发初体验(二)

    支持Silverlight的Windows Embedded Standard 好了,完成安装之后,我们就可以来做Windows Embedded Standard的第一个操作系统镜像了.在开始菜单中 ...

  7. 深度探索Hyperledger技术与应用之超级账本初体验(附部署代码)

    2019独角兽企业重金招聘Python工程师标准>>> 本章零基础地介绍了如何快速体验超级账本搭建的区块链网络,我们先绕过了比较复杂的初始化配置,用官方提供的fabric-sampl ...

  8. Spring环境搭建,IoC容器初体验~

    由于最近的任务是关于IoC配置文件格式的转换,所以需要从Spring的IoC容器开始学起,今天根据网上的介绍搭建了Spring环境,并对其IoC容器进行了初体验.文章中涉及到的软件以及推荐的一本关于S ...

  9. 来自新手Banana Pi香蕉派初体验

    2019独角兽企业重金招聘Python工程师标准>>> 一.前言 一段时间来对有强大的技术支持和完善的社区的Raspberry Pi很感兴趣,本想入一片学习学习,但转念一想Raspb ...

最新文章

  1. Scala入门到精通——第八节 包和引入
  2. 学习之旅——工作记录日志2017.7.09
  3. 容量耦合系数模型_期刊在线 | 基于ALE流固耦合方法的刷式密封泄漏特性理论与实验研究...
  4. 整个电脑键盘被锁住了_蜗居共享经济,如何彻底榨干你家里的电子设备|鼠标|共享经济|键盘|电脑桌|显示器|升降支架...
  5. Tcl Tutorial 笔记9 · proc 参数传递与return
  6. 小程序 长按复制文本
  7. 多媒体技术教程——信噪比
  8. 市区对应的编码获取入库过程
  9. Agv、Rgv 车辆控制调度系统开发第七篇-选车算法
  10. 《人机交互技术》 第五章 界面设计
  11. walking机器人入门教程-离线建图-cartographer算法建图
  12. HTTP/3 强势来袭?!
  13. 百分点科技启动上市:消息称其国内业务持续亏损,苏萌为实控人
  14. Aiseesoft Mac Video Converter Ultimate for Mac(视频转换工具)
  15. 机器学习中的数学——粒子群算法(Particle Swarm Optimization, PSO)(三):改进的粒子群算法
  16. 如何用MATLAB进行电路仿真
  17. iOS游戏开发中使用自定义字体的方法
  18. 一文带你了解防爆伺服电机适用的危险场所分类、分区和分组
  19. Python实战24天从入门到精通-大纲
  20. 文件格式转换云平台 360converter.com

热门文章

  1. 【C】 4个数排列组合
  2. 代理ip会不会影响网络速度和稳定性
  3. Linux进程监测和操控之top、ps、kill、nice、renice命令
  4. flutter点击空白区域失去输入框焦点
  5. 密码学基础--仿射密码
  6. [浪子学编程][读书笔记]-道法自然之用例分析
  7. Java的BigDecimal,对运算封装
  8. 简单介绍下h5广告的特点
  9. android 统计应用流量 NetworkStatsManager
  10. C语言的历史(转)(译)