標籤:soft on() frame inf 修改 連結 參數 指定 for
某個項目中涉及到這樣一個情景: 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.HostingImports Microsoft.Scripting.HostingPublic 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 SubEnd Class
這樣我們就通過IronPython完成了VB調用Python指令碼方法,我們可以繼續參考如下串連: 41985163
這裡Python的指令碼方法非常單純無暇,沒有任何的其他指令碼的引用, 但是實際項目中這樣單純的代碼大多是沒有意義的,總會引用其他的module來實現更加複雜的邏輯。
下面我們就要進階了,如果Python指令碼之間有相互的引用,如何完成我們的目標呢?請看如下步驟
4):在相同的目錄中建立另外一個Python檔案來實現檔案的讀寫,檔案名稱為 mytest_common.py,
import osclass 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 FileOperatordef MyTestReadInfo(): fInfo = fOperator.ReadInfoFromFile("D:\Code\PyTest\Test.txt") return fInfofOperator = FileOperator()
6):然後我們用如下VB代碼進行對新的Python指令碼方法的調用
Imports IronPython.HostingImports Microsoft.Scripting.HostingPublic 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 SubEnd 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 syssys.path.append(".\Lib")from mytest_common import FileOperatordef MyTestReadInfo(): fInfo = fOperator.ReadInfoFromFile("D:\Code\PyTest\Test.txt") return fInfofOperator = 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/
41985163
在.Net Framework中調用Python的指令碼方法 (以VB和C#為例)