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