C#调用Python的最优方式

BIMCoder梁老师 BIMCoder梁老师 2020-07-03

原文链接

https://mp.weixin.qq.com/s?src=11&timestamp=1609665236&ver=2806&signature=5Iq9r-GodyRcD8aBdJrdiqlxQzXj05Kn-X6Q7h-zXe4gMAT2WWTUveRgxFPkrx1ZIj08Zw-abnEQHrOU5*8TYtgXKICj0cM0Lbx0RNOgljiogKpuaY0BtFsFDAK23SWE&new=1

一、引言:

最近一直在用Tensorflow训练模型,经过普华永道数字方案组AI杨大师的细心指导与耐心帮助,总算把模型训练的比较靠谱了。由于Revit二次开发主要使用C#语言,如何在C#环境中调用Python脚本,并且得到Python运行结果成为了目前紧迫的问题。经过连续通宵的艰苦奋战和试错,接下来,我将告诉大家一个比较靠谱的方案及编程细节。

二、选择

1.如果在百度中搜索C#调用Python,大多数出现的结果是使用IronPython,但是目前的状况是IronPython对Python2的支持比较好,而目前许多Python代码都已经转成Python3,IronPython对Python3的兼容并没有达到完美。而我的Python脚本是Python3,所以在尝试性的使用IronPython并测试不顺后,果断放弃IronPython。

2.在Python中使用Tensorflow的情况,如果在百度中搜索C#调用python Tensorflow,大多数结果会安利你去使用TensorflowSharp,该库是专门用于使用C#语言搭建Tensorflow程序。但我负责任的告诉你,别上它们的当!Tensorflow在Python写作是最佳的,不要浪费时间花在转语言上面。

三、正文

那么如果我写了一段Tensorflow Python脚本,我该如何在C#环境中调用呢,Python脚本需要进行哪些改造才能让C#顺利的调用呢??请跟随梁老师的脚步!

1.C#的调用方式,注意点:

a.如果你需要传个矩阵给Python脚本,将你的矩阵保存成csv文件,让Python脚本去读这个文件,得到矩阵数据;

b.如果只传递普通的数字,字符串,那么直接通过arguments传递即可:

var result = string.Empty;
var pypath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "My.py");

var p = new ProcessStartInfo();

var sArguments = pypath;

sArguments += " "+param1+" "+ param2;

p.FileName = @"D:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\python.exe";

p.Arguments = sArguments;

p.UseShellExecute = false;

p.RedirectStandardError = true;

p.RedirectStandardOutput = true;

p.CreateNoWindow = true;

using (Process process = Process.Start(p))

{

using (StreamReader reader = process.StandardOutput)

{

string stderr = process.StandardError.ReadToEnd();

result = reader.ReadToEnd();

}

}

在上述例子中,我将两个参数param1与param2带入到名为My.py的Python脚本中,然后运行后的结果会返回到result中。

2.Python脚本的改造。如果Python脚本既需要得到C#传过来的csv文件,又需要接收单独的入参,同时输出结果给C#,那么可以这样编写:

# -*- coding:utf-8  -*-

#前面的我就不写了

if __name__ == "__main__":

dir = sys.argv[1]

path = os.path.join(dir,'Mydata.csv')

r = np.genfromtxt(open(path,"rb"),delimiter=",")[:,:-1]

final = int(sys.argv[2])

q_network = DeepNet(dir,r,final)

result = q_network.get(r,final)

print(result)

记住!结果一定要用print()出来,而且在Python脚本里不要有其他地方使用print(),不然会把所有print()内容都会发到C#的result里。有些可以结构化的数据可以先转成json字符串再让C#接收,在C#中使用Newtonsoft再把json编程结构化对象。

(0)

相关推荐