打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用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.Executeobject>(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.Executeobject>(scope); Console.WriteLine(result);

输出结果变为:Hello 123

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

publicclass Foo { publicstring 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.Executeobject>(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.Executeobject>(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 DateTimeprint('My birthday is %s' %foo.Birthday.ToString())

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

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

from System import *

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

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

import clr,sysclr.AddReference('Foo')from Foo import Foofoo = 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。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
不同程序语言之间的互动,IronPython 与C#交互
在.NET中嵌入IronPython 交互
Python 3.8 新特性全面解读
在C#中调用python方法
C#中调用python
python获取文件当前路径方法汇总
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服