嵌入IronPython,内置帮助命令,我的CLR对象

时间:2011-01-08 19:16:07

标签: c# ironpython embedding

我将IronPython(2.6.1)嵌入到C#程序集中,并将几个对象暴露给使用PythonEngine.ExecuteFile执行的脚本。我用

暴露它们
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对象上添加描述性文本到help()的输出?就像你可以在脚本中,你的python本地类型?我的第一个猜测是DescriptionAttribute,但是没有用。

(*)显然,最终的工作脚本不会这样做,但在编写/测试脚本时它非常有用。

回答

这是一个完整的控制台程序,演示了如何导入用标准python库help()替换无用内部help()的站点。

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;
    }
}

1 个答案:

答案 0 :(得分:4)

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

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