初步了解IronPython
装了Ironpython还需要装Python吗?
----IronPython 是一种在 NET 和 Mono 上实现的 Python 语言,由 Jim Hugunin(同时也是 Jython 创造者)所创造.
IronPython是优雅的python编程语言和强大的.NET平台的有机结合。使用动态类型系统得以将Python移植到NET Framework上。
可以形象的说,Ironpython就像是Python的一种方言,所以装了Ironpython就已经是安装了Python了。
----Ironpython就是在Python.NET下的实现,CPython是C下的Python实现,都是同一个东东,所以装了Ironpython并不需要装Python,当然两者也可以共存。
----不需要,Ironpython就是.NET下实现的Python
使用IronPython集成Python和.NET http://python.jobbole.com/80982/
从两个优秀的世界各取所需,更高效的复用代码。想想就醉了,.NET和python融合了。“懒惰”的程序员们,还等什么?
Jesse Smith为您展示如何两个语言来服务同一个.NET程序。你能集两家所长:Python和.NET一起工作,提供可重用的代码功能而不需要你为了一个环境重写代码库。
通过使用IronPython 运行时库,你可以让Python脚本运行在你的.NET程序中。本文向你展示如何使用一个.NET程序中的python脚本获取并展示用户反馈。
如果你曾经有在一个.NET程序中运行Python脚本的需求,整合两者最好的办法是使用IronPython。我有过这样的需求。我曾经效力的一个组织需要扩展一个已经存在于一个.NET地图程序中的工具集。我们的目的是利用另一个工具集中现有的Python代码来扩展这个已有的工具集,前者还不是后者的一部分。在做了一番研究之后,我决定使用IronPython,事情进展很顺利。
本文基于上述项目的经验,我会还原当时的场景,对你所处的情境也同样适用。
对于这个我们所期望的解决方案,首先要面对的挑战是从将要运行在.NET程序中的那个Python脚本获取输出,然后使用一个.NET程序的对话框把这个输出展示给用户。让我感到吃惊的是,这么做比预想的还要简单,你同样也能学到如何去做同样的事情。整个过程相对比较简单,我们将在下面的章节中进行概述。
在.NET程序中嵌入Python脚本
在这个例子中,我向你展示如何在一个Windows桌面程序中嵌入Python脚本。目的是在一个已有的程序中添加一个新的工具按钮。点击按钮后,程序会弹出一个对话框,显示一个嵌入在对话框代码中的Python脚本的运行结果。
为了给这个例子铺垫更多的前因后果,我们这个应用程序是一个桌面地图软件,可以让用户创建他们自己的地图。这个新的工具允许用户解析和标准化他们地图上的地址点。
标准化一个地址,就意味着要确保这个地址有一个街道名,前缀或后缀,房屋或建筑编号,以及连接该街道的上一条街道和下一条街道。每一个地址段必须遵循US邮局邮编地址标准指导。
假设已有一个Python脚本已经可以做到这些;它就是例子中执行解析的脚本。Python脚本将会通过当前对话框在屏幕上输出或闪现这个正在解析的地址,我们可以通过选择地址解析工具来触发对话框(我不想说的太细,仅仅解释到这里。)
代码并不重要,重要的是知道如何嵌入脚本和如何定向脚本的输出到对话框,作为程序的一部分显示在屏幕上。这一过程像下面这样进行:
- 用户启动地图程序并打开一个自定义地图。
- 用户从屏幕上方的已有的工具集中选择一个新的地址标准化工具。
- 弹出一个带有可以启动地址标准化进程的启动按钮的地址标准化对话框
- 一个文本框显示当前正在被解析的地址。这些文本框很快消失,地址在用户眼前一闪而过,表示过程启动并且正在解析。
- 出现一个表示整个过程结束的信息,使用了第4步中同样的文本框。
确定源代码和项目
首先要做的事情是确定脚本应该嵌入到应用程序源代码的什么位置。在我们的例子/情境下,这个位置应该是添加到包含工具集项目中的新的对话框。这个对话框会被一个已经存在的用于处理工具栏点击事件的方法所触发
当我们确定了需要包含源代码的项目后,就需要引用IronPython 库。
如果你使用Visual Studio作为编辑器的话,最简单的方法是使用Nuget Package Manager来添加IronPython库到项目中。你可以搜索”IronPython”,然后运行时库就可以在包管理工具中选择了。
嵌入脚本
接下来做的才是真正嵌入脚本。你首先要用脚本引擎(scripting engine)来设置一个Python脚本引擎实例。在添加脚本前,你同样可以设置任何你的脚本所需的特殊的路径。
1
2
3
4
5
6
|
; html-script: false ]ScriptEngine pyEngine = Python.CreateEngine();
pyEngine.Runtime.IO.RedirectToConsole();
var paths = pyEngine.GetSearchPaths();
paths.Add(@"C:Python27Lib");
paths.Add(@"C:Python27Libsite-packages");
pyEngine.SetSearchPaths(paths);
|
第二行告诉.NET框架Python引擎的运行时库会将输出重定向到控制台。然而,这并不是重定向到我们为这个应用添加的新的工具所需的对话框中。(下面的代码会做这个工作)
但是,首先我们需要通过一个简单的字符串变量来添加脚本。你需要改变你的脚本中的引号来配合字符串的引号工作。
一个简单的方法是把你脚本中的所有双引号变成单引号。嵌入脚本的语法如下:
1
2
3
4
|
; html-script: false ]string thescript =
@"
(此处为实际脚本内容)
";
|
你可能需要处理一些格式问题,但是缩进必须一致。在脚本字符串解析一个有效的字符串后,是时候添加输出重定向代码让脚本的输出显示在工具的对话框窗口中了:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
; html-script: false ]Console.SetOut(TextWriter.Synchronized(new TextBoxWriter(statusText)));
pyEngine.Execute(thescript);
this.AllDone(FINISHED);
}
catch (Exception ex)
{
this.AllDone(ex.InnerException.StackTrace);
}
}
public void AllDone(string message)
{
buttonStart.Enabled = true;
this.statusLabel.Text = message;
}
|
在上面这段代码中,我们设置了一个新的TextWriter,它接受一个TextBoxWriter类型的参数,这使得我们可以把脚本的输出重新写到一个文本框中。TextBoxWriter类型的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
; html-script: false ]public class TextBoxWriter : TextWriter
{
private TextBox _textBox;
public TextBoxWriter(TextBox textbox)
{
_textBox = textbox;
}
public override void Write(char value)
{
base.Write(value);
// When character data is written, append it to the text box.
_textBox.AppendText(value.ToString());
}
public override System.Text.Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
}
|
传入TextBoxWriter类型的statusText属性是我们的文本框,它会出现在对话框中,显示脚本的输出。我们的Python脚本中的每一个输出语句都会被重定向到这个文本框。
结论
在本文中,你学会了如何把Python脚本集成到一个.NET程序中,并且把Python的脚本文件输出到一个.NET对话框。这种无缝衔接,用户是不会感觉到的,他们并不知道实际上是Python在处理后台的一些工作。
在很多场合下,集成两种语言是很有用的。我分享了的这一情景,为我的处境提供了很好的解决方案。你可以按照类似的步骤,用同样的方法把它应用在很多场合。
我建议你去建立一个自己的简单范例,甚至使用Python脚本文件把Python代码直接加入到.NET应用中,你确实可以这样做。当然你并不需要直接把脚本嵌入在.NET源代码中,但对我来说这样做最方便。
--------------------------------------------------------------------------------------
http://developer.51cto.com/art/200910/157697.htm
学习IronPython最简单的方法就是使用它,我们建议您下载安装IronPython 2.6。下载的安装程序包含了二进制文件、Python标准程序库、用于Silverlight的IronPython和一个教程。此外,还有一个成为Pyc.py的工具,该工具可以把IronPython应用程序编译成二进制文件。
Ipy.exe可以用来执行IronPython程序,对于熟悉Python语言及探索.NET程序集来说非常有用。在本文中,交互会话使用>>> 来表示。
- >>> from System import Array
- >>> help(Array.CreateInstance)
- Help on built-in function CreateInstance:
- CreateInstance(...)
- Array CreateInstance(Type elementType, Array[int] lengths)
五、与.NET的集成
IronPython本身是用C# 写成的。IronPython使用原生的.NET类型,例如IronPython中的字符串类型即.NET字符串类型,整数类型即Int32,等等。通过使用Python的导入手段,我们就能够访问.NET程序库和类。
在使用.NET framework时,通常要导入clr模块,该模块含有用来为程序集添加索引之类的函数。一旦为程序集添加了引用,我们就能够从该程序集的命名空间中导入类。下面以Windows Forms为例进行说明:
- >>> import clr
- >>> clr.AddReference(\'System.Windows.Forms\')
- >>> from System.Windows.Forms import Application, Button, Form
- >>>
- >>> form = Form(Text="Hello World")
- >>> button = Button(Text="Click Me")
- >>> form.Controls.Add(button)
- >>>
- >>> def onClick(sender, event):
- ... print \'Ouch!\'
- >>> button.Click += onClick
- >>> Application.Run(form)
- Ouch!
- Ouch!
下面我们对上述代码中有关的Python语法做相应的介绍。
1. 这里通过Form和Button构造函数的关键字参数来设置有关属性。
2. 事件处理函数(onClick)是一个标准的Python函数,IronPython会在幕后调用按钮单击处理程序(EventHandler)。
注意,在Python中,语句结构是用缩排表示的,而不是花括号。onClick函数体相对于其声明来说,要做缩进处理。
六、Dir函数与help函数
在通过交互式解释器进行学习的时候,有两个函数非常有用,它们分别是dir与help函数。Dir(some_object)常用来返回一个对象的所有成员,它们会作为字符串列表返回,而在Python中,我们可以根据需要对列表进行过滤或分割处理。例如,这里我们将显示系统命名空间中所有以字母“I”开头的成员:
- >>> import System
- >>> for member in dir(System):
- ... if member.startswith(\'I\'):
- ... print member
- ...
- IAppDomainSetup
- IAsyncResult
- ICloneable
- IComparable
- IConvertible
- ICustomFormatter
- IDisposable
- IEquatable
- IFormatProvider
- IFormattable
- (and so on...)
- >>>
Help(some_object)函数能够为我们提供一个对象更为详细的信息。提供help函数,我们可以打印出对象的所有方法,并针对个别方法再次调用该函数以获取进一步的信息:
- >>> from collections import namedtuple
- >>> help(namedtuple)
- Help on function namedtuple in module collections:
- namedtuple(typename, field_names, verbose=False)
- Returns a new subclass of tuple with named fields.
- >>> Point = namedtuple(\'Point\', \'x y\')
- >>> Point.__doc__ # docstring for the new class
- \'Point(x, y)\'
- >>> p = Point(11, y=22) # instantiate with positional args or keywords
- >>> p[0] + p[1] # indexable like a plain tuple
- 33
- >>> x, y = p # unpack like a regular tuple
Collections模块是Python标准程序库的一部分,namedtuple是一个类制造厂,我们可以使用它新建其行为类似枚举类型(Python没有内建的枚举类型)的类:
- >>> from collections import namedtuple
- >>> Point = namedtuple(\'Point\', \'x y\')
- >>> point = Point(1, 3)
- >>> point
- Point(x=1, y=3)
- >>> point.x
- 1
- >>> point.y
- 3
在运行时新建类是动态语言的优点之一。
七、设置sys.path
使用交互式解释器时,一个重要因素是当我们执行导入语句或者为程序集添加引用时,Python需要到哪里去查找。默认时,所有标准.NET框架都可以被引用。另外IronPython安装程序也包含有Python标准程序库。对于别的东西,我们需要告诉IronPython到哪里查找python模块和程序集。
Python用于查找python模块时,需要用到称为sys.path的系统模块中的一个Python列表。对于IronPython来说,当我们为程序集添加引用的时候,IronPython也是通过sys.path来指出到哪里去寻找程序集的。为了将一个新目录添加到搜索路径,只需将该路径作为字符串附加上去就行,具体如下所示:
- >>> import sys
- >>> path = \'c:\\Projects\\MyProject\'
- >>> sys.path.append(path)
- >>> import clr
- >>> clr.AddReference(\'MyAssembly\')
由于字符串中的反斜杠被用作转义字符使用,因此我们必须在路径中使用双反斜杠。
到这里,对于IronPython所需要了解的基础知识也介绍的差不多了。如果你对于在.NET平台上运行Python感兴趣,那么就来试试看IronPython吧!