最近做一个Python和C#的交互写个记录
#coding=utf-8 加上这个python支持中文
python调用C#中的方法
import clr;
#加载DLL文件三种方式
#clr.AddReference("Python.Core") #clr.AddReferenceToFile("Python.Core.dll"); clr.AddReferenceToFileAndPath("D:\\Python.Core.dll"); #导入命名空间 from test import FuncOfPython;如果是静态方法就可以直接FuncOfPython.Test()来调用
实例成员的话
pythonTest=test();
pythonTest.Test()
最开始是使用Nuget安装的IronPython,这样安装没有基本类库,后来去官网下载安装,然后引用DLL。
public static dynamic ExcutePython(string algorithm, string pyStr, string funName, dynamic par)
{ //判断是否存在字典中 if (!scriptDic.ContainsKey(algorithm)) { //创建Python引擎,DLR 动态语言执行类,用于解析和执行动态脚本 ScriptEngine engine = Python.CreateEngine(); //设置基本类库的路径 ICollection<string> paths = engine.GetSearchPaths(); paths.Add(@"D:\工具安装\IronPython-2.7.5\Lib"); engine.SetSearchPaths(paths); //创建一个执行上下文,其中保存了环境及全局变量。宿主(Host)可以通过创建不同的 ScriptScope 来提供多个数据隔离的执行上下文。 ScriptScope scope = engine.CreateScope(); //操控动态语言代码的类型,我们可以编译(Compile)、读取(Read Code Lines)或运行(Execute)代码。 ScriptSource source = engine.CreateScriptSourceFromString(pyStr); //运行输入脚本 dynamic context = source.Execute(scope); Tuple<ScriptEngine, ScriptScope, ScriptSource> temp = Tuple.Create<ScriptEngine, ScriptScope, ScriptSource>(engine, scope, source); scriptDic.Add(algorithm, temp); } //从字典中取出 Tuple<ScriptEngine, ScriptScope, ScriptSource> script = scriptDic[algorithm]; //调用方法,并传参数 Func<dynamic, dynamic> result = script.Item2.GetVariable<Func<dynamic, dynamic>>(funName); return result(par); }上面是我封装的方法动态执行脚本。
其实也可以context.你脚本中的方法来执行也是没有问题的
注意要版本一致,不一致也会出现这个问题,我是Nuget安装的2.7.7版本,然后去官网下载2.7.7版本的mis文件,安装完事,可以直接引用第三方包
第三方包踩坑:
编写的文件打印出来的地址与安装标准包安装地址不匹配,导致引入第三方会报错
No module named random
后来查下资料,打印出来的路径指向是我程序路径,修改下就好了,打印路径方法
#打印第三方包路径
#import sys #print sys.path设置第三方包路径的相关代码
//设置第三方包路径
List<string> Paths = new List<string>(); Paths.Add(PythonPackage); engine.SetSearchPaths(Paths);这样就可以引用安装的python标准包了。
但是有个地方,没有弄明白,如果是解压版的IronPython,引用第三方包如果不是.py文件,比如time模块,这种是c写的包,解压版本引入会报错,引入不了,如果安装版本的IronPython,就可以引用。
踩坑2:
IronPython random 随机数模块存在个问题,生成的随机数不会超过设定值的一半,比如:
import random
random.randint(0,4)生成的随机数会出现0,1,2永远不会出现3,4,原因未知。
解决方案1:既然是一半,就*2
解决方案2:调用c#的Random类来实现
import System
from System import Random r=Random() r.Next(0,100)踩坑3:
在练习的时候发现一个问题,调试模式下运行py,其中调用C#中的类,例如from System import Math,会一直报一个错误,IronPython.Runtime.Exceptions.ImportException not a Zip file,很奇怪为什么出现,后来找遍国内资源没有找到,后来在国外一网站发现一小伙也有这个问题,然后茅塞顿开,出现这个问题是仅在调试模式出现,直接运行是没有这个问题的,出现这个错误多按几次F5调过去,是可以过去的。