ironpython使用dictionary_在C#环境中动态调用IronPython脚本(一)
本文講述用C#調用Ironpython運行環境,解析并運行動態pyhton腳本。這種情況應用在那些需要滯后規定行為的場合,例如,動態計算項(計算引擎),用戶可以自定義計算內容、計算公式等。
本文的代碼適用于IronPython 2.7(需要下載及安裝)及C#4.0,由于IronPython早期版本提供的Hosting API不同,對于網上搜索得到的代碼,如果是早期版本代碼(多數如此),并不能編譯通過,所以本文強調代碼的版本問題。
本文代碼需要引用兩個命名空間IronPython和Microsoft.Scripting (文件位置分別為IronPython 2.7的安裝目錄下的IronPython.dll和Microsoft.Scripting.dll)。
一、最簡單的例子
先看一個最簡單的例子,C#環境與Python環境沒有數據聯系。
public?static?void?test1()
{
var?engine?=?IronPython.Hosting.Python.CreateEngine();
engine.CreateScriptSourceFromString("print?'hello?world'").Execute();
Console.ReadLine();
}
如果IronPython環境建立好,運行test1(),就會得到正確的結果。如果只想運行一段腳本,就是這般簡單。
二、C#環境調用Python環境函數
以上的例子沒有實用價值,再看第二個例子,這個例子演示了如何從C#環境調用Python環境中的函數以及類中方法。
public?static?void?test2()
{
var?engine?=?Python.CreateEngine();
var?scope?=?engine.CreateScope();
var?source?=?engine.CreateScriptSourceFromString(
"def?adder(arg1,?arg2):\n"?+
"???return?arg1?+?arg2\n"?+
"\n"?+
"def?fun(arg1):\n"?+
"???tel?=?{'jack':?4098,?'sape':?4139}\n"?+
"???for?k,?v?in?arg1.iteritems():\n"+
"??????tel[k]=v\n"+
"???return?tel\n"?+
"\n"?+
"class?MyClass(object):\n"?+
"???def?__init__(self,?value):\n"?+
"???????self.value?=?value\n");
source.Execute(scope);
var?adder?=?scope.GetVariable>("adder");
Console.WriteLine(adder(2,?2));
var?fun?=?scope.GetVariable>("fun");
IronPython.Runtime.PythonDictionary?inputDict?=?new?IronPython.Runtime.PythonDictionary();
inputDict["abc"]?=?"abc";
inputDict["def"]?=?456;
object?res?=?fun(inputDict);
IronPython.Runtime.PythonDictionary?outputDict?=?res?as?IronPython.Runtime.PythonDictionary;
foreach?(var?k?in?outputDict.Keys)
{
Console.WriteLine("key:"+?k.ToString()+"?val:??"?+?outputDict[k].ToString());
}
var?myClass?=?scope.GetVariable>("MyClass");
var?myInstance?=?myClass("hello");
Console.WriteLine(engine.Operations.GetMember(myInstance,?"value"));
}
上面代碼中,python中有兩個函數和一個類,第一個函數的參數是簡單數據類型,第二個是復雜數據類型(關于兩個環境下復雜數據類型的對應,下面將論述)。無論是類還是函數,C#的調用方法都是通過ScriptScope.GetVariable,它的函數定義如下:
T GetVariable(string name);
ScriptScope還有一個更“安全”的方法
boolTryGetVariable(string name, out T value);
可以完成相似的操作。
這個例子,可以擴展C#的應用,例如,python有豐富的數學計算庫,而C#在這方面較欠缺,這時,就可以采用上面的方式,計算部分采用現成的python庫,而主控程序采用C#編制。
三、在Python環境中調用C#環境函數
現在看第三個例子,如果Python運行邏輯復雜,需要在運行過程中調用C#函數怎么辦?
public?static?void?test3()
{
var?engine?=?Python.CreateEngine();
var?scope?=?engine.CreateScope();
scope.SetVariable("my_object_model",?new?CSharpClass?());
string?pythonscript?=
"def?fun(arg1):\n"?+
"???result?=?arg1+1\n"?+
"???return?result\n"?+
"adder?=?fun(5)?+?my_object_model.Foo(2)\n"?;
engine.CreateScriptSourceFromString(pythonscript).Execute(scope);
Console.WriteLine(scope.GetVariable("adder"));
}
Class?CSharpClass
{
public?int?Foo(int?arg)
{
return??arg?+1;
}
}
這個例子中,創建CShparpClass類,并將其作為“變量”傳到Python環境中,在Python中就可以調用了。注意到C#中的類名可以和Python中不一樣。
四、在Python環境中動態調用C#庫
在這種情況下,Python腳本和C#庫都是“滯后”于主應用才編寫出來的,可以滿足用戶現場定制行為(采用Python腳本),并且可以給Python腳本傳入現場定制的參數。
首先,建立一個C#庫,代碼如下:
namespace?LibforPython
{
public?class?PythonLib
{
public?int?Test(int?x,?string?op)
{
switch?(op.ToUpper())
{
case?"INC":
return?x?+?1;
case?"DEC":
return?x?-?1;
}
return?x?+?1;
}
}
}
編譯成LibforPython.dll后拷貝到主運行程序的運行目錄(二者同目錄)。調用代碼如下:
public?static?void?test4()
{
var?engine?=?Python.CreateEngine();
var?scope?=?engine.CreateScope();
engine.Runtime.LoadAssembly(Assembly.LoadFrom("LibforPython.dll"));??????????????string?pythonscript?=
"from?LibforPython?import?PythonLib\n"?+
"o?=?PythonLib()\n"?+
"res?=?o.Test(6,'add')\n";
engine.CreateScriptSourceFromString(pythonscript).Execute(scope);
Console.WriteLine(scope.GetVariable("res"));
}
運行以上程序即可。這個例子中,LibforPython.dll是在運行時才引入Python環境中的。對于預先已知的Python可能用到的接口,才用例三的辦法更好些,對于預先無法預先定義或“遺忘”的接口,采用本例比較適合。
五、總結
將Python環境“寄宿”于C#環境,進而動態執行用戶自定義的腳本,是應用可配置性、靈活性的一種體現(其他動態語言也可以這么做,以Ironpython比較簡單)。這一過程包括以下三步:
var engine = Python.CreateEngine();
var scope = engine.CreateScope();
var source = engine.CreateScriptSourceFromString(“…”);
source.Execute(scope);
Python環境與宿主環境的交互(參數傳入、傳出),則通過ScriptScop的GetVariable和SetVariable進行。
總結
以上是生活随笔為你收集整理的ironpython使用dictionary_在C#环境中动态调用IronPython脚本(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: apache php mysql下载_l
- 下一篇: E350主板内存条选择攻略,一定要看