使用IronPython给.Net程序加点料

开发的时候,经常被策划频繁变动的方案而苦恼。这时候就想要加入点动态语言来辅助一下。

在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调用。在卸载的时候遇到了问题,虽可以通过应用程序域来绕过,但这又加入了应用程序域之间的交互。没有动态语言来的方便。

IronPython的官网:http://ironpython.codeplex.com/

在C#中使用IronPython

新建一个项目,ConsoleApplication

然后NuGet添加IronPython包

在Main函数中编写如下代码:

    ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello world!')";
var sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

这里用到了三个主要类型:ScriptEngine, ScriptScope, ScriptSource

顾名思义ScriptEngine是引擎,ScriptScope相当于一个容器可用于传递一些自定义的变量,ScriptSource就是脚本源码。

运行后输出结果:Hello world!

C#向IronPython传递变量

将上面的代码修改如下

            ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello %d' %number)";
scope.SetVariable("number", 123);
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

输出结果变为:Hello 123

还可以试试更奇妙的,比如C#定义一个类

    public class Foo
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
}

传入这个变量试试,修改Main函数的代码

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = @"print('Hello %s' %foo.Name)
foo.DoSth()";//注意这里换行是必须的
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(1999,2,2)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

成功输出:Hello 阿萨德

那么如果调用Foo里的方法呢?可以哦,你可以试一试,还能够命中断点呢!

执行IronPython文件

将script字符串替换为文件路径,使用ScriptEngine的CreateScriptSourceFromFile方法可以执行文件格式的IronPython

新建文件,名为test.py, 将上面的script字符粘贴到文件内。修改文件的属性为“如果较新则复制”。

那么Main函数的代码段就是:

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string path = @"test.py";
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(1999,2,2)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromFile(path);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);

执行成功,输出结果不变。

但是此时编辑器对py文件的支持是木有的,此时可以安装一个插件,Python Tools for Visual Studio 简称PTVS,可以在GitHub上获取到:https://github.com/Microsoft/PTVS/releases

安装之后,就有了语法高亮和智能提示哦~

这个工具增加了很多对Python的支持,你还能在新建项目中看到新增的Python模板,包括了Django等一些流行的Python网站模板,当然IronPython的模板也是不可少的。

在IronPython中使用C#的类型

还有一个问题,刚才在foo中定义了Birthday这个属性,但是它的类型是DateTime,如何在IronPython中使用它呢?

修改test.py文件中的代码

print('Hello %s' %foo.Name)
foo.DoSth()
from System import DateTime
print("My birthday is %s" %foo.Birthday.ToString())

这里我使用了from System import DateTime这行语句就引入了DateTime的类型

同样的,你也可以引入System程序集中的String、TimeSpan等类型,方便得一塌糊涂,比如这样

from System import *

如果需要添加程序集引用呢?

比如我新建了一个类库,将Foo类放到了这个新的类库中,那么我要使用Foo的时候,只要这样:

import clr,sys
clr.AddReference('Foo')
from Foo import Foo foo = Foo()
foo.Name = "haha" print('Hello %s' %foo.Name)
from System import *
print("My birthday is %s" %foo.Birthday.ToString())

或许你的程序将告诉你一个找不到Module的错误,那就把Foo.dll拷贝到你的执行目录下。或者你也可以修改Main函数中的代码,使用engine.SetSearchPaths(new[]{@"../Foo/bin/Debug"});设置查找类库的路径。

如果报告无法在Foo中找到Foo类型,那就是你拷贝Foo类的代码到类库中去的时候没有使用Foo类库的namespace。

其他

现在已经知道了如何在C#中使用IronPython,以及在IronPython的代码中使用C#的类型和变量传递,那么就可以在你的C#程序中加入炫酷的脚本语言动态特性了。

关于CreateScriptSource的时机,你或许可以使用FileSystemWatcher类来监视文件修改,不过要注意多线程问题哦。

如果你并不需要在C#中加入IronPython,而仅仅只是想要用Python一样的语法来做一些.net的程序比如winform、wpf之类的,你可以安装IronPython的安装包,安装包在最上面给出的官网地址中有下载。安装之后将获得IronPython单独运行的环境和相关的文档。

然后你就可以通过PTVS帮你新增的几个IronPython项目模板来创建你的IronPython程序了。

而且,他们是支持断点调试的哦!你是不是有了好点子呢,比如在C#项目中使用Link文件来链接IronPython项目中的py文件,^_^

我已经迫不及待地想要写一个可以编辑脚本的小游戏来玩玩了呢。

最后加一个在GitHub上看到的IronPython的小游戏Sample

使用IronPython给.Net程序的更多相关文章

  1. 使用IronPython给.Net程序加点料

    开发的时候,经常被策划频繁变动的方案而苦恼.这时候就想要加入点动态语言来辅助一下. 在考虑用动态语言之前也曾想过使用动态加载dll的方式,实现基础接口来调用.在卸载的时候遇到了问题,虽可以通过应用程序 ...

  2. IronPython和C#交互

    IronPython和C#交互 IronPython是一个.NET平台上的Python实现,包括了完整的编译器.执行引擎与运行时支持,能够与.NET已有的库无缝整合到一起. IronPython已经很 ...

  3. Python之路3【第一篇】Python基础

    本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...

  4. Python之路【第一篇】:Python简介和入门

    python简介: 一.什么是python Python(英国发音:/ pa θ n/ 美国发音:/ pa θɑ n/),是一种面向对象.直译式的计算机程序语言. 每一门语言都有自己的哲学: pyth ...

  5. Python系列教程(一):简介

    Python发展历史 起源 Python的作者,Guido von Rossum,荷兰人.1982年,Guido从阿姆斯特丹大学获得了数学和计算机硕士学位.然而,尽管他算得上是一位数学家,但他更加享受 ...

  6. Python应用场景

    Web应用开发 Python经常被用于Web开发.比如,通过mod_wsgi模块,Apache可以运行用Python编写的Web程序.Python定义了WSGI标准应用接口来协调Http服务器与基于P ...

  7. 2.python数据类型

    1 Number(数字) 2   字符串类型(string)   字符串内置方法 # string.capitalize() 把字符串的第一个字符大写 # string.center(width) 返 ...

  8. Python之路【第一篇】:Python简介和入门

    python简介: 一.什么是python Python(英国发音:/ pa θ n/ 美国发音:/ pa θɑ n/),是一种面向对象.直译式的计算机程序语言. 每一门语言都有自己的哲学: pyth ...

  9. 1.python简介

    简介 1.python语言介绍 python的创始人:Guido Van Rossum 2.python是一门什么样的语言 编程语言主要从以下几个角度进行分类:编译型,静态型,动态性,强类型定义语言和 ...

随机推荐

  1. Linux 命令 快捷命令综合

    FTP开机启动 启动要让FTP每次开机自动启动,运行命令:  chkconfig --level 35 vsftpd on linux 关机 1.halt linux 注销 1.logout linu ...

  2. 用数组array代替CActiveRecord构建CArrayDataProvider

    当需要构建 GridView的时候: 常常用 CArrayDataProvider 或者 CActiveDataProvider 这是就需要一个CActiveRecord 比如:  857       ...

  3. ZOJ 2334(Monkey King-左偏树第一题)

    Monkey King Time Limit: 10 Seconds      Memory Limit: 32768 KB Once in a forest, there lived N aggre ...

  4. hdu2457 Trie图+dp

    hdu2457 给定n个模式串, 和一个文本串 问如果修改最少的字符串使得文本串不包含模式串, 输出最少的次数,如果不能修改成功,则输出-1 dp[i][j] 表示长度为i的字符串, 到达状态j(Tr ...

  5. WPF之Binding深入探讨--Darren

    1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储.逻辑和界面三层之间流通,所以站在数据的角度上来看,这三层都很重要.但算法在3层中的分布是不均匀的,对于一个3层结构的 ...

  6. 初步C++类模板学习笔记

    类模板 实现:在上课时间的定义给它的一个或多个参数,这些参数代表了不同的数据类型.                              -->抽象的类. 在调用类模板时, 指定參数, 由编 ...

  7. C# Windows Phone 8 WP8,切换各国语系免重开机 加速开发 送审有效率!!

    原文:C# Windows Phone 8 WP8,切换各国语系免重开机 加速开发 送审有效率!! 一般我们在开发Windows Phone 8 时,会考虑到各国语言的问题,但是你有想过吗?用实体手机 ...

  8. bat脚本命令

    注:本文转载地址 http://www.cnblogs.com/yefengmeander/archive/2011/12/01/2887978.html 1.Echo 命令  打开回显或关闭请求回显 ...

  9. simpleDateFormat日期格式转换

    1------------------------------------------------------------------------------------- package com.n ...

  10. 设计Mysql索引的原则

    1. 搜索的索引列,不一定是所要选择的列.换句话说,最适合索引的列是出如今WHERE 子句中的列,或连接子句中指定的列,而不是出如今SELECT keyword后的选择列表中的列. 2. 使用惟一索引 ...