2011-01-27 31 views
2

我正在嘗試將[rlcompleter][1]功能添加到IronTextBoxControl2的中。如何在託管IronPython 2.0時發佈模塊「__main__」?

不過,我有一個很難麻煩線路:

import __main__ 
rlcompleter.py

。這是因爲我沒有這樣的模塊。我一直在搜索/篩選IronPython 2.0代碼庫,試圖找出如何發佈模塊。

看來我可以從IronPython.Runtime.PythonContext的實例與PublishModule(string name, PythonModule module)的方法這樣做。但我遇到了下列麻煩:

  • 獲得PythonContext實例
  • 獲得PythonModule實例

,是ScriptEngineScriptScope。我希望範圍將作爲模塊__main__發佈。據我所知,範圍已經附加到模塊,但我不知道如何訪問它。

這裏是代碼的時候,我想這綁在一起:

/// <summary> 
    /// Set up an IronPython environment - for interactive shell or for canned scripts 
    /// </summary> 
    public void SetupEnvironment(ScriptEngine engine, ScriptScope scope) 
    {       
     // add variables from Revit 
     scope.SetVariable("__revit__", _commandData.Application); 
     scope.SetVariable("__commandData__", _commandData); 
     scope.SetVariable("__message__", _message); 
     scope.SetVariable("__elements__", _elements); 
     scope.SetVariable("__result__", (int)Result.Succeeded);       

     // add preconfigures variables 
     scope.SetVariable("__vars__", RevitPythonShellApplication.GetVariables()); 

     /* register scope as __main__ module here?! */   

     // add the search paths 
     AddSearchPaths(engine); 
    } 

回答

1

沒關係,我通過IronPython的2.0.3源代碼去與想出了以下內容:

  • 一個PythonContextMicrosoft.Scripting.Runtime.LanguageContext
  • 可以通過Microsoft.Scripting.Hosting.Providers.HostingHelpers.GetLanguageContext(ScriptEngine)方法得到ScriptEngine的語境
  • 如果你有一個用於python的ScriptEngine,那麼你可以投射。

哇。所以現在我終於有了我的PythonContext!所以我打電話給CreateModulePublishModule,在喝茶之前回家!

等等。不,首先,CreateModule的第二個參數是Microsoft.Scripting.Runtime.Scope。我們所有的是Microsoft.Scripting.Hosting.ScriptScope。其中碰巧包含Scope,除了它的訪問者是internal。所以我們需要先做一些反思。

這裏是我的示例代碼增強由我提出的解決方案:

/// <summary> 
/// Set up an IronPython environment - for interactive shell or for canned scripts 
/// </summary> 
public void SetupEnvironment(ScriptEngine engine, ScriptScope scriptScope) 
{ 
    // add variables from Revit 
    scriptScope.SetVariable("__revit__", _commandData.Application); 
    scriptScope.SetVariable("__commandData__", _commandData); 
    scriptScope.SetVariable("__message__", _message); 
    scriptScope.SetVariable("__elements__", _elements); 
    scriptScope.SetVariable("__result__", (int)Result.Succeeded);   

    // add preconfigures variables 
    scriptScope.SetVariable("__vars__", RevitPythonShellApplication.GetVariables()); 

    // add the current scope as module '__main__' 
    var languageContext = Microsoft.Scripting.Hosting.Providers.HostingHelpers.GetLanguageContext(engine); 
    var pythonContext = (IronPython.Runtime.PythonContext)languageContext; 
    var module = pythonContext.CreateModule(null, GetScope(scriptScope), null, IronPython.Runtime.ModuleOptions.None);    
    pythonContext.PublishModule("__main__", module); 

    // add the search paths 
    AddSearchPaths(engine); 
} 

/// <summary> 
/// Be nasty and reach into the ScriptScope to get at its private '_scope' member, 
/// since the accessor 'ScriptScope.Scope' was defined 'internal'. 
/// </summary> 
private Microsoft.Scripting.Runtime.Scope GetScope(ScriptScope scriptScope) 
{ 
    var field = scriptScope.GetType().GetField(
     "_scope", 
     System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 
    return (Microsoft.Scripting.Runtime.Scope) field.GetValue(scriptScope); 
} 

我一直目的的所有類型的命名空間。我發現IronPython代碼很難遵循,並且經常會對定義在哪裏的東西感到困惑。

2

我遇到了同樣的問題。我試圖使用ScriptEngine.Execute *來運行代碼。結果使用ScriptEngine.CreateScriptSourceFromFile,然後調用ExecuteProgram解決了這個問題。

退房的完整的解決方案如下:trouble executing Selenium python unittests in C# with ScriptEngine (.NET 3.5)

注:IronPython的2.7使得這整個事情更容易:

public void SetupEnvironment(ScriptEngine engine, out ScriptScope scope) 
{ 
    scope = IronPython.Hosting.Python.CreateModule(engine, "__main__"); 
    return; 
} 
相關問題