我将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;
}
}
答案 0 :(得分:4)
我的猜测是,在您的应用中,您没有导入标准库。 IronPython包含一个内置的帮助功能,标准库包含一个由site.py安装的帮助功能。如果您在托管时确保标准库可用,然后在创建引擎时导入site.py,那么您应该获得标准库帮助。据说这可能是一个错误或缺少的功能,内置帮助没有记录事件和属性。
关于文档 - 是的,您只需要使用C#的doc注释并使用/doc:MyAssemblyName.xml选项进行构建。如果XML文件与程序集位于同一目录中,IronPython将读取doc字符串并为 doc 属性提供帮助()然后读取。