2013-01-21 93 views
1

我正在將IronPython嵌入到C#中,作爲修改我正在使用的程序的一種方法。因此,有多個文件需要一次使用。編譯所有文件C#/ IronPython

 Code = ""; 
     Engine = Python.CreateEngine(); 
     Runtime = Engine.Runtime; 
     var files = Directory.GetFiles("script", "*.py", SearchOption.AllDirectories); 
     foreach (var tr in files.Select(file => new StreamReader(file))) 
     { 
      Code += "\n"; 
      Code += tr.ReadToEnd(); 
      tr.Close(); 
     } 
     Scope = Engine.CreateScope(); 

     Engine.CreateScriptSourceFromString(AddImports(Code)).Execute(Scope); 

這需要的所有文件/腳本,並把它們組合成一個字符串有一個腳本源從他們創建的,這是當然的,有缺陷的方法,因爲如果類不按字母繼承訂單,UnboundNameException將發生

class bar(foo): 
    pass 

class foo(): 
    pass 

我該如何去編譯所有的文件以正常的方式?

回答

2

如果您將代碼/文件構建爲python modules,則導入並使用它們,python運行庫將處理/解決您的導入和依賴關係。 比方說你有一個包含我們的主入口主蟒蛇文件A.py

import B, C 
foo = B.Foo() 
bar = C.Bar() 

foo.foo() 
bar.bar(foo) 

print("done") 

此文件使用模塊Ç定義B.pyC. py

B.py:

class Foo: 
    def foo(self): 
     print("Foo.foo()") 

C.py(注意模塊Ç用途/進口模塊以及):

import B 
class Bar: 
    def bar(self, foo): 
     print("Bar.bar()") 

在.NET樣板(假設A.py,B.py and C.py駐留在同一個目錄中自稱對建立發動機和執行一切你的.NET二進制或您路徑上)看起來像

var engine = Python.CreateEngine(); 
var scope = engine.CreateScope(); 
var source = engine.CreateScriptSourceFromFile("A.py"); 
source.Execute(scope); 

注意,只有A.py(作爲主入口點)必須加載和一切將由運行時解決。

如果您的腳本被拆分爲多個文件夾,則可能需要相應地更改搜索路徑。假設除A.py您的所有文件駐留在一個名爲腳本文件夾中可能看起來像

var paths = engine.GetSearchPaths(); 
paths.Add("scripts"); 
engine.SetSearchPaths(paths); 

請注意,如果由於某種原因,你想用你的類時,爲了避免模塊命名空間,你可以還導入*。這對於某些使用情況可能更容易,但可能會產生命名衝突(例如,如果AB將定義類別Foo)。

from B import * 
from C import * 
foo = Foo() 
bar = Bar() 
+0

我的python腳本不會相互交互,只能與C#部分交互。我是否需要/生成一個導入所有內容的Python腳本? –

+1

這取決於他們如何「與C#部分交互」。如果腳本「在.NET中執行某些操作」一旦被加載,它們必須從.NET或python加載。您的python腳本可能不會在運行時間意義上彼此交互,但它們中的類/類型彼此依賴。是否可以拆分包含入口點和庫腳本的文件?或者你可以從.net調用某種定義的入口函數?然後你可以直接從.net加載它們並獲得輸入函數。 –

+0

沒有入口點,只有庫腳本。 –