本文由 伯乐在线 - 艾凌风 翻译,Daetalus 校稿。未经许可,禁止转载!
英文出处:www.informit.com。欢迎加入翻译组。

从两个优秀的世界各取所需,更高效的复用代码。想想就醉了,.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脚本将会通过当前对话框在屏幕上输出或闪现这个正在解析的地址,我们可以通过选择地址解析工具来触发对话框(我不想说的太细,仅仅解释到这里。)

代码并不重要,重要的是知道如何嵌入脚本和如何定向脚本的输出到对话框,作为程序的一部分显示在屏幕上。这一过程像下面这样进行:

  1. 用户启动地图程序并打开一个自定义地图。
  2. 用户从屏幕上方的已有的工具集中选择一个新的地址标准化工具。
  3. 弹出一个带有可以启动地址标准化进程的启动按钮的地址标准化对话框
  4. 一个文本框显示当前正在被解析的地址。这些文本框很快消失,地址在用户眼前一闪而过,表示过程启动并且正在解析。
  5. 出现一个表示整个过程结束的信息,使用了第4步中同样的文本框。

确定源代码和项目

首先要做的事情是确定脚本应该嵌入到应用程序源代码的什么位置。在我们的例子/情境下,这个位置应该是添加到包含工具集项目中的新的对话框。这个对话框会被一个已经存在的用于处理工具栏点击事件的方法所触发

当我们确定了需要包含源代码的项目后,就需要引用IronPython 库。

如果你使用Visual Studio作为编辑器的话,最简单的方法是使用Nuget Package Manager来添加IronPython库到项目中。你可以搜索”IronPython”,然后运行时库就可以在包管理工具中选择了。

嵌入脚本

接下来做的才是真正嵌入脚本。你首先要用脚本引擎(scripting engine)来设置一个Python脚本引擎实例。在添加脚本前,你同样可以设置任何你的脚本所需的特殊的路径。

 
 
 
 
 
 

Python

 
; 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);
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引擎的运行时库会将输出重定向到控制台。然而,这并不是重定向到我们为这个应用添加的新的工具所需的对话框中。(下面的代码会做这个工作)

但是,首先我们需要通过一个简单的字符串变量来添加脚本。你需要改变你的脚本中的引号来配合字符串的引号工作。

一个简单的方法是把你脚本中的所有双引号变成单引号。嵌入脚本的语法如下:

 
 
 
 
 
 

Python

 
; html-script: false ]string thescript =
@"
(此处为实际脚本内容)
";
1
2
3
4
;html-script:false]stringthescript=
       @"
       (此处为实际脚本内容)
       ";

你可能需要处理一些格式问题,但是缩进必须一致。在脚本字符串解析一个有效的字符串后,是时候添加输出重定向代码让脚本的输出显示在工具的对话框窗口中了:

 
 
 
 
 
 

Python

 
; 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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
;html-script:false]Console.SetOut(TextWriter.Synchronized(newTextBoxWriter(statusText)));
                pyEngine.Execute(thescript);
                this.AllDone(FINISHED);
            }
            catch(Exceptionex)
            {
                this.AllDone(ex.InnerException.StackTrace);
            }
        }
        public void AllDone(stringmessage)
        {
            buttonStart.Enabled=true;
            this.statusLabel.Text=message;
        }

在上面这段代码中,我们设置了一个新的TextWriter,它接受一个TextBoxWriter类型的参数,这使得我们可以把脚本的输出重新写到一个文本框中。TextBoxWriter类型的代码如下:

 
 
 
 
 
 

Python

 
; 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; }
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
;html-script:false]public classTextBoxWriter:TextWriter
        {
            private TextBox _textBox;
            public TextBoxWriter(TextBox textbox)
            {
                _textBox=textbox;
            }
            public override void Write(char value)
            {
                base.Write(value);
                //When character data iswritten,append it to the text box.
                _textBox.AppendText(value.ToString());
            }
            public override System.Text.Encoding Encoding
            {
                get{returnSystem.Text.Encoding.UTF8;}
            }
        }
    }

传入TextBoxWriter类型的statusText属性是我们的文本框,它会出现在对话框中,显示脚本的输出。我们的Python脚本中的每一个输出语句都会被重定向到这个文本框。

结论

在本文中,你学会了如何把Python脚本集成到一个.NET程序中,并且把Python的脚本文件输出到一个.NET对话框。这种无缝衔接,用户是不会感觉到的,他们并不知道实际上是Python在处理后台的一些工作。

在很多场合下,集成两种语言是很有用的。我分享了的这一情景,为我的处境提供了很好的解决方案。你可以按照类似的步骤,用同样的方法把它应用在很多场合。

我建议你去建立一个自己的简单范例,甚至使用Python脚本文件把Python代码直接加入到.NET应用中,你确实可以这样做。当然你并不需要直接把脚本嵌入在.NET源代码中,但对我来说这样做最方便。

 

出处:http://python.jobbole.com/80982/

使用IronPython集成Python和.NET的更多相关文章

  1. 工程脚本插件方案 - c集成Python基础篇(VC++嵌入Python)

    序: 为什么要集成脚本,怎么在工程中集成Python脚本. 在做比较大型的工程时,一般都会分核心层和业务层.核心层要求实现高效和稳定的基础功能,并提供调用接口供业务层调用的一种标准的框架划分.在实际中 ...

  2. eclipse中集成python开发环境

    转载:https://www.cnblogs.com/mywood/p/7272487.html Eclipse简介 Eclipse是java开发最常用的IDE,功能强大,可以在MAC和Windos上 ...

  3. idea集成python插件

    idea集成python插件 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在继承安装Python插件时,请确认你是否安装Python解释器(Python官网:https://ww ...

  4. [IDEA_6] IDEA 集成 Python

    0. 说明 在 IDEA 中集成 Python 1. IDEA 集成 Python 1.1 Ctrl + Alt + S 进入设置 依次选中 Settings  -->  Plugins  -- ...

  5. Windows系统下在Eclipse中集成Python

    我现在偶尔开发代码,已经不用Eclipse了,主要原因是查看Jar包中的代码反编译十分不便,项目加载的时候卡,偶尔还会崩溃 用Intellij IDEA和PyCharm 原来的笔记如何在Eclipse ...

  6. 工程脚本插件方案 - c集成Python基础篇

    序: 为什么要集成脚本,怎么在工程中集成Python脚本. 在做比较大型的工程时,一般都会分核心层和业务层.核心层要求实现高效和稳定的基础功能,并提供调用接口供业务层调用的一种标准的框架划分.在实际中 ...

  7. 自动化打包资源混淆集成python实践----资源混淆

    前面自动化打包资源混淆集成python实践----打包一文讲述了四种打包方案,以及美团打包方案.apk注释添加渠道号方案的实现.这里讲集成资源混淆. 1.资源混淆带来的好处: 1)对资源文件起一定的保 ...

  8. c#利用IronPython调用python的过程种种问题

    c#利用IronPython调用python的过程种种问题 小菜鸟一枚,最新学习了Python,感觉语言各种简短,各种第三方类库爽歪歪,毕竟之前是从c#转来的,看到Python的request类各种爽 ...

  9. 精通 Oracle+Python,第 9 部分:Jython 和 IronPython — 在 Python 中使用 JDBC 和 ODP.NET

    成功的编程语言总是会成为顶级开发平台.对于 Python 和世界上的两个顶级编程环境 Java 和 Microsoft .NET 来说的确如此. 虽然人们因为 Python 能够快速组装不同的软件组件 ...

随机推荐

  1. linux服务器最大连接数

    1 受内存限制 每个tcp连接是一个打开的socket文件,因此linux服务器的最大连接数受linux操作系统单个进程同时打开的最大文件数的限制. 这个限制本质上是对单个进程内存的限制. 查看进程最 ...

  2. iOS main函数讲解

    int main(int argc, char * argv[]) { @autoreleasepool { //四个参数 主要讲解后面两个参数 /* 第三个参数:UIApplication或者其子类 ...

  3. Bootstrap学习-菜单-按钮-导航

    1.下拉菜单(基本用法) 在使用Bootstrap框架的下拉菜单时,必须调用Bootstrap框架提供的bootstrap.js文件.当然,如果你使用的是未编译版本,在js文件夹下你能找到一个名为“d ...

  4. Android笔记之使用Glide加载网络图片、下载图片

    Glide简介 不想说太多,真的很方便:P)可以节省我不少时间 GitHub地址:https://github.com/bumptech/glide 加载网络图片到ImageView Glide.wi ...

  5. PAT 1055. 集体照 (25)

    拍集体照时队形很重要,这里对给定的N个人K排的队形设计排队规则如下: 每排人数为N/K(向下取整),多出来的人全部站在最后一排: 后排所有人的个子都不比前排任何人矮: 每排中最高者站中间(中间位置为m ...

  6. Linux开启防火墙后,设置允许通过的端口

    安装Firewall命令: yum install firewalld firewalld-config Firewall开启端口命令: firewall-cmd --zone=public --ad ...

  7. pg 和sql server 分别如何新建二进制数据库字段以及插入二进制数据的sql语句

    PG create table demo ( id int, name bytea ); Insert into demo (id,name)values(256,pg_read_binary_fil ...

  8. HDU 4824 Disk Schedule

    //

  9. PHP网站在Linux服务器上面的安全配置

    本文详细总结了PHP网站在Linux服务器上面的安全配置,包含PHP安全.mysql数据库安全.web服务器安全.木马查杀和防范等,很好很强大很安全. PHP安全配置 1. 确保运行php的用户为一般 ...

  10. basic--factory

    <?php /* 工厂模式: 由工厂类根据参数来决定创建出哪一种产品类的实例: 工厂类是指包含了一个专门用来创建其他对象的方法的类.所谓按需分配,传入参数进行选择,返回具体的类.工厂模式的最主要 ...