【轉載】http://zh.5long.me/2015/dotnet-call-python/
前言
InronPython是一種在.NET和Mono上實現的Python語言,使用InronPython就可以在.NET環境中調用Python代碼,非常方便。
本文主要介紹在C#中調用Python代碼,並使用Python安裝的第三方模塊。
安裝InronPython
要在.NET環境中使用Python,先要安裝InronPython(當然也要安裝Python),安裝很簡單,直接下載安裝就行。在CodePlex就有下載,下載地址:
還可以把 Python Tools for Visual Studio 也安裝了。
使用
添加引用庫
在Visual Studio新建一個工程后,添加引用IronPython.dll和Microsoft.Scripting.dll(位於InronPython的安裝目錄下,如下圖)。
C#代碼內嵌Python
最簡單的使用方式如下:
var engine = IronPython.Hosting.Python.CreateEngine();
engine.CreateScriptSourceFromString("print 'hello world!'").Execute();
從文件中加載Python代碼
一般情況下我們還是要把Python代碼單獨寫在文件中。在工程中新建一個Python文件,如 hello.py ,並設置其屬性Copy to Output Directory的值為Copy if newer。在hello.py下編寫如下代碼:
def say_hello():
print "hello!"
def get_text():
return "text from hello.py"
def add(arg1, arg2):
return arg1 + arg2
C#代碼如下:
var engine = IronPython.Hosting.Python.CreateEngine();
var scope = engine.CreateScope();
var source = engine.CreateScriptSourceFromFile("hello.py");
source.Execute(scope);
var say_hello = scope.GetVariable<Func<object>>("say_hello");
say_hello();
var get_text = scope.GetVariable<Func<object>>("get_text");
var text = get_text().ToString();
Console.WriteLine(text);
var add = scope.GetVariable<Func<object, object, object>>("add");
var result1 = add(1, 2);
Console.WriteLine(result1);
var result2 = add("hello ", "world");
Console.WriteLine(result2);
使用Python安裝的第三模塊
問題
到此為止,程序運行得很順利。可是好景不長,最近用Python寫了個程序要使用rsa加密,在Python中安裝了rsa模塊(下載地址: https://pypi.python.org/pypi/rsa/3.1.1 )后,直接運行Python代碼沒問題,可是在C#代碼調用時就報異常,異常信息如下:
An unhandled exception of type 'IronPython.Runtime.Exceptions.ImportException' occurred in Microsoft.Dynamic.dll
Additional information: No module named rsa
沒有找到模塊,經過一番google,說是要設置 sys.path ,如下:
import sys
sys.path.append(r"c:\python27\lib")
照做之后問題依舊。不過想一想,應該是sys.path還沒設置對。
解決
先在python代碼加上下面幾行:
import sys
sys.path.append(r"c:\python27\lib")
print sys.path
運行查看輸出,在對比Python環境下的 sys.path ,果然不一樣,問題應該就出在 sys.path 上了。
在cmd下分別打開python和IronPython(在IronPython安裝目錄下的ipy64.exe或ipy.exe),執行 import sys;print sys.path ,對比輸出:
python:
['', 'C:\\Python27\\lib\\site-packages\\setuptools-12.0.3-py2.7.egg', 'C:\\Pytho
n27\\lib\\site-packages\\rsa-3.1.1-py2.7.egg', 'C:\\Python27\\lib\\site-packages
\\pyasn1-0.1.7-py2.7.egg', 'C:\\Windows\\SYSTEM32\\python27.zip', 'C:\\Python27\
\DLLs', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\
lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\site-packages']
IronPython:
['.', 'C:\\Program Files (x86)\\IronPython 2.7\\Lib', 'C:\\Program Files (x86)\\
IronPython 2.7\\DLLs', 'C:\\Program Files (x86)\\IronPython 2.7', 'C:\\Program F
iles (x86)\\IronPython 2.7\\lib\\site-packages']
分別在兩個環境在執行 import rsa ,Python環境正常,IronPython環境下報ImportError: No module named rsa異常。在IronPython環境下執行如下操作:
sys.path.append('C:\\Python27\\lib\\site-packages\\setuptools-12.0.3-py2.7.egg')
sys.path.append('C:\\Python27\\lib\\site-packages\\rsa-3.1.1-py2.7.egg')
再次 import rsa ,不報異常了。
對應的python代碼文件加上如下幾行:
import sys
sys.path.append('C:\\Python27\\lib')
sys.path.append('C:\\Python27\\lib\\site-packages\\setuptools-12.0.3-py2.7.egg')
sys.path.append('C:\\Python27\\lib\\site-packages\\rsa-3.1.1-py2.7.egg')
import rsa
再次運行,Ok!
