2011-01-27 37 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; 
} 
相关问题