在.Net Framework中调用Python的脚本方法 (以VB和C#为例)
某个项目中涉及到这样一个情景: VB/C#写的原始项目要调用Python的一些方法完成特殊的操作, 那么这就涉及到了,在.Net Framework中如何调用Python的脚本方法。
具体步骤流程如下所示:
1): 展示一个简单的Python代码,即传递一个参数,然后返回修改后字符串,此文件名称为 mytest.py
def MyTestFunction(name):
return "testing " + name
2): 我们借助第三方的工具来实现这个操作,那么这个第三方工具就是 IronPython,IronPython是一种在.Net及Mono上的Python实现,是一个基于微软的DLR引擎的开源项目,可以去这里下载或者跟踪源代码(https://github.com/IronLanguages/ironpython2)。 然后我们可以到这个链接中下载安装文件(https://github.com/IronLanguages/ironpython2/releases/tag/ipy-2.7.8), 安装文件安装完之后我们可以到对应的安装目录下面找到我们所需要的dll(IronPython.dll, IronPython.Modules.dll, Microsoft.Dynamic.dll, Microsoft.Scripting.dll)以及一个名为Lib的文件夹,如下图所示:
3):我们用VS创建一个VB的工程,然后将上面的这四个dll引用进来,之后就可以进行具体的调用了,假设我们的Python代码文件放置的目录是 D:\Code\PyTest\mytest.py 必要时请将此文件copy到VB执行目录中, 然后把对应的pythonPath换掉
如下代码所示:
Imports IronPython.Hosting
Imports Microsoft.Scripting.Hosting Public Class Form1
Private Sub CallPython()
Dim pythonPath = "D:\Code\PyTest\mytest.py"
Dim pyruntime as ScriptRuntime = Python.CreateRuntime()
Dim fileObj As Object = pyruntime.UseFile(pythonPath)
Dim result = fileObj.MyTestFunction("World")
End Sub
End Class
这样我们就通过IronPython完成了VB调用Python脚本方法,我们可以继续参考如下连接: https://blog.csdn.net/letunihao/article/details/41985163
这里Python的脚本方法非常单纯无暇,没有任何的其他脚本的引用, 但是实际项目中这样单纯的代码大多是没有意义的,总会引用其他的module来实现更加复杂的逻辑。
下面我们就要进阶了,如果Python脚本之间有相互的引用,如何完成我们的目标呢?请看如下步骤
4):在相同的目录中创建另外一个Python文件来实现文件的读写,文件名为 mytest_common.py,
import os class FileOperator: def WriteInfoToFile(self, path):
file = open(path, "w")
file.write("Hello World")
file.close() def ReadInfoFromFile(self, path):
fileInfo = ""
data = open(path)
for each_line in data:
fileInfo += each_line
data.close()
return fileInfo
为什么实现方法的时候要加入一个额外的参数 self?
请看如下连接: https://stackoverflow.com/questions/23944657/typeerror-method-takes-1-positional-argument-but-2-were-given/42016399
文件读写请参考 (http://www.pythonforbeginners.com/files/reading-and-writing-files-in-python)
5):然后我们对 mytest.py 文件做如下修改,假设我们已经通过Python自己运行WriteInfoToFile方法已经生成了一个Test.txt文件
from mytest_common import FileOperator def MyTestReadInfo():
fInfo = fOperator.ReadInfoFromFile("D:\Code\PyTest\Test.txt")
return fInfo fOperator = FileOperator()
6):然后我们用如下VB代码进行对新的Python脚本方法的调用
Imports IronPython.Hosting
Imports Microsoft.Scripting.Hosting Public Class Form1
Private Sub CallPython()
Dim pythonPath = "D:\Code\PyTest\mytest.py"
Dim pyruntime as ScriptRuntime = Python.CreateRuntime()
Dim fileObj As Object = pyruntime.UseFile(pythonPath)
Dim result = fileObj.MyTestReadInfo()
End Sub
End Class
会throw exception说:某某某某module无法加载, 或者是找不到某某module。Unhandled Exception: IronPython.Runtime.Exceptions.ImportException: No module named ...
原因是:Python自己运行的时候会自动加载对应相关联的module,特别是一些系统的module,比如这里面的 os, 但是我们通过外部调用的时候无法自动建立这样的链接,因为我们要在Python的源文件中明确指明所引用的那些系统源文件所在folder,让其可以在指定的folder下面去寻找相关联的源文件。
那么这些源文件在什么地方呢?我们可以到Python的安装目录下寻找,也可以到我们第2步 IronPython的安装目录下面寻找,即Lib文件夹,然后将此文件夹copy到我们的测试Python的同级文件夹,用相对路径指定,当然你也可以不用copy,然后用绝对路径定位到Lib文件夹即可
代码如下所示:
import sys
sys.path.append(".\Lib") from mytest_common import FileOperator def MyTestReadInfo():
fInfo = fOperator.ReadInfoFromFile("D:\Code\PyTest\Test.txt")
return fInfo fOperator = FileOperator()
这样我们再用第6步中的VB代码去调用就可以成功了。
注:使用相对路径时,请注意使用文件的位置,保证能够成功定位到。
更多详细信息可以参考如下连接:
https://stackoverflow.com/questions/6195781/ironpython-exe-compiled-using-pyc-py-cannot-import-module-os
https://thesesergio.wordpress.com/2013/09/11/how-to-generate-and-use-a-exe-that-uses-net-dlls-with-ironpython-pyc-py/
https://blog.csdn.net/letunihao/article/details/41985163
给出C#部分代码以作参考
public static dynamic GetPythonFileObj()
{
var fath = AppContext.BaseDirectory + @"Services\PythonService.py"; var pyruntime = Python.CreateRuntime();
var pyengine = pyruntime.GetEngine("Python");
var paths = pyengine.GetSearchPaths();
paths.Add(AppContext.BaseDirectory + @"Services");
paths.Add(AppContext.BaseDirectory + @"Services\Lib");
pyengine.SetSearchPaths(paths); dynamic fileObj = pyruntime.UseFile(fath);
return fileObj;
} public static string UploadTag(ref dynamic fileObj, string tagName)
{
var tagValue = fileObj.ex_read(tagName);
return tagValue.ToString();
}
在.Net Framework中调用Python的脚本方法 (以VB和C#为例)的更多相关文章
- C++中调用Python脚本
C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库, 需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了 先看Python的代码 代 ...
- C++中调用Python脚本(转载)
转载▼ 标签: 杂谈 C++中调用Python脚本的意义就不讲了,至少你可以把它当成文本形式的动态链接库,需要的时候还可以改一改,只要不改变接口, C++的程序一旦编译好了,再改就没那么方便了先看Py ...
- C#中调用python方法
最近因为项目设计,有部分使用Python脚本,因此代码中需要调用python方法. 1.首先,在c#中调用python必须安装IronPython,在 http://ironpython.codepl ...
- 如何在Java中调用Python代码
有时候,我们会碰到这样的问题:与A同学合作写代码,A同学只会写Python,而不会Java, 而你只会写Java并不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方设法“调 ...
- 在Java中调用Python
写在前面 在微服务架构大行其道的今天,对于将程序进行嵌套调用的做法其实并不可取,甚至显得有些愚蠢.当然,之所以要面对这个问题,或许是因为一些历史原因,或者仅仅是为了简单.恰好我在项目中就遇到了这个问题 ...
- 在Java中调用Python代码
极少数时候,我们会碰到类似这样的问题:与A同学合作写代码, A同学只会写Python,不熟悉Java ,而你只会写Java不擅长Python,并且发现难以用Java来重写对方的代码,这时,就不得不想方 ...
- 在QT C++中调用 Python并将软件打包发布(裸机可运行)
为了提高工作效率,需要一个可以自动生成多份相关联的word文档免去繁琐复制粘贴工作的软件.最后选定使用QT C++做界面和主要逻辑程序设计,对word的操作使用python写好对应的函数,然后在QT中 ...
- VC中调用COM组件的方法(转载)
原文参考:http://hi.baidu.com/mingyueye/item/53ebecd44da76917d80e4449 总结一下在VC中调用COM组件的方法 准备及条件: COM服务器为进程 ...
- (转)DedeCms Runphp 标签中调用其他变量的方法
DedeCms Runphp 标签中调用其他变量的方法 我们都知道,在DedeCMS中是可以使用PHP的,常见的方法就是if else了,例如模板制作中,我们需要对来源和作者进行判断,如果为空,则提示 ...
随机推荐
- 服务器配置 ssl 证书
最近因为公司的 服务器 ssl证书即将到期(服务器 和 ssl证书管理都在 腾讯云上), 所以为了能顺利的 重新申请 ssl证书 ,我和小伙伴 在他的个人服务器上尝试了一波(我们居然都不会 ...) ...
- python12--字符串的比较 函数的默认值的细节 三元表达式 函数对象 名称空间 作用域 列表与字典的推导式 四则运算 函数的嵌套
复习 1.字符串的比较; 2.函数的参数; ******实参与形参的分类: 3.函数的嵌套调用: # 字符串的比较# -- 按照从左往右比较每一个字符,通过字符对应的ascii进行比较 ...
- Money King【题解】
我又傻了……竟然忘了区别大根堆和小根堆的性质,以至于一个符号打错,debug了半天……(我真是太菜了……) 题目描述 Once in a forest, there lived N aggressiv ...
- Python菜鸟快乐游戏编程_pygame(2)
Python菜鸟快乐游戏编程_pygame(博主录制,2K分辨率,超高清) https://study.163.com/course/courseMain.htm?courseId=100618802 ...
- xgboost-Python&R
sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...
- Java虚拟机—垃圾回收算法(整理版)
1.概述 由于垃圾收集算法的实现涉及大量的程序细节.因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程.主要涉及的算法有标记-清除算法.复制算法.标记-整理算法.分代收集算法. 2 ...
- jenkins 自动化部署执行shell
# -*- coding:utf-8 _*-""" @author:Administrator @file: new_app_publish.py @time: 2018 ...
- 递归处理vue菜单数据
结构不多说,bean的封装很简单,直接上核心代码吧,自己根据需要把不要的属性自己过滤掉: public List<MenuBo> getMenuByUserId(Long user_id, ...
- C51学习
十六个数字循环显示 #include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar uns ...
- python 单例实现
class View: _instance = None def __new__(cls, *args, **kwargs): if cls._instance is None: cls._insta ...