2011-01-08 67 views
10

我将IronPython(2.6.1)嵌入到C#程序集中,并将多个对象暴露给使用PythonEngine.ExecuteFile执行的脚本。我揭露他们要么嵌入IronPython,内置帮助命令,我的CLR对象

scope.SetVariable("SomeObject", new SomeObject()) 

engine.Execute("from MyNamespace import SomeObject", scope) 

取决于脚本如何使用它们。我的应用程序组件添加到发动机

engine.Runtime.LoadAssembly(Assembly.GetExecutingAssembly()) 

现在的脚本可以执行help(SomeObject)并转储可爱的小帮助信息(*),但这是不完整的。没有任何对象的事件或属性(当然是公共的)显示出来,并且很多“内置”成员也缺失。

这里的奇数部分;如果我火了ipy.exe并执行以下命令:

import sys 
sys.path.append('<location of my app>') 
import clr 
clr.AddReferenceToFile('myapp.exe') 
from MyNamespace import SomeObject 
help(SomeObject) 

我得到了不同的转储,完全与所有缺少的成员!

为什么两者不同?

奖金的问题:假设我得到它的正常工作,是否有可能在我的CLR对象添加描述性文字,以帮助输出()?就像你可以从脚本中,在你的Python本地类型?我的第一个猜测是DescriptionAttribute,但没有奏效。 (*)显然,最终的工作脚本不会这样做,但它在编写/测试脚本时非常有帮助。

回答

下面是说明如何导入与标准Python库的帮助替换usless内部帮助()()网站的完整控制台程序。

using System; 
using System.Collections.Generic; 
using System.Reflection; 
using IronPython.Hosting; 
using IronPython.Runtime; 
using Microsoft.Scripting.Hosting.Providers; 

namespace MyApp 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Work around issue w/ pydoc - piping to more doesn't work so instead indicate that we're a dumb terminal 
      if (Environment.GetEnvironmentVariable("TERM") == null) 
       Environment.SetEnvironmentVariable("TERM", "dumb"); 

      var engine = Python.CreateEngine(); 

      // Add standard Python library path (is there a better way to do this??) 
      PythonContext context = HostingHelpers.GetLanguageContext(engine) as PythonContext; 
      ICollection<string> paths = context.GetSearchPaths(); 
      paths.Add(@"C:\Program Files (x86)\IronPython 2.6\Lib"); 
      context.SetSearchPaths(paths); 

      // Import site module 
      engine.ImportModule("site"); 

      engine.Runtime.LoadAssembly(Assembly.GetEntryAssembly()); 

      var scope = engine.CreateScope(); 
      scope.SetVariable("SomeObject", new SomeObject()); 
      engine.Execute("help(SomeObject)", scope); 
     } 
    } 

    /// <summary> 
    /// Description of SomeObject. 
    /// </summary> 
    public class SomeObject 
    { 
     /// <summary> 
     /// Description of SomeProperty. 
     /// </summary> 
     public int SomeProperty { get; set; } 
     /// <summary> 
     /// Description of SomeMethod. 
     /// </summary> 
     public void SomeMethod() { } 
     /// <summary> 
     /// Description of SomeEvent. 
     /// </summary> 
     public event EventHandler SomeEvent; 
    } 
} 

回答

4

我的猜测是,在你的应用程序中,你并没有导入标准库。 IronPython包含一个内置的帮助功能,标准库包含一个由site.py安装的帮助功能。如果确保标准库在主持时可用,然后在创建引擎时导入site.py,则应该获得标准库帮助。这就是说这可能是一个错误或缺少的功能,内置的帮助不记录事件和属性。

关于文档 - 是的,您只需使用C#的doc注释并使用/doc:MyAssemblyName.xml选项进行构建即可。如果XML文件与程序集位于同一目录中,IronPython将读取文档字符串并为它们提供帮助()然后读取的属性。

+0

我能确认这个答案是正确的,但我不是(到目前为止)能够弄清楚如何以编程方式导入site.py。我的验证包括构建ipy.exe(它是一个简单的.cs文件)并尝试上面的ipy过程。我得到了失败的帮助结果。如果我然后使标准的python库可用于这个新的ipy.exe,我得到正确的帮助结果。因此,加载标准库的解决方案深埋在Microsoft.Scripting.Hosting或IronPython.Hosting的碗中。 OO-Spaghetti对于这个混乱将是一句善意的话。 – Tergiver 2011-01-09 16:23:25