Я внедряю 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)
я получаю другую свалку, в комплекте со всеми отсутствующими членами!
Почему эти два отличаются?
Bonus вопрос: Предположим, что я получаю это работает правильно, можно добавить описательный текст на мои объекты CLR на выходе помощи()? Как вы можете из скрипта, в ваших родных типах python? Мое первое предположение было DescriptionAttribute, но это не сработало.
(*) Очевидно, что окончательный рабочий сценарий не будет делать этого, но он чрезвычайно полезен при написании/тестировании сценария.
Ответил
Вот полная консольная программа, которая иллюстрирует, как импортировать сайт, который заменяет 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;
}
}
Я был в состоянии проверить, что этот ответ правильный, однако я пока не могу понять, как импортировать сайт.py программно. Моя проверка состояла в создании ipy.exe (это всего один простой .cs-файл) и попытка процедуры ipy выше. Я получаю разбитые результаты помощи. Если я затем сделаю стандартную библиотеку python доступной для этого нового ipy.exe, я получу правильные результаты справки. Таким образом, решение по загрузке стандартной библиотеки зарывается глубоко в чаши Microsoft.Scripting.Hosting или IronPython.Hosting. OO-Spaghetti было бы добрым словом для этого беспорядка. – Tergiver
Я понял, как загрузить модуль сайта и обновить мой вопрос выше. – Tergiver