Sto incorporando IronPython (2.6.1) in un assembly C# ed esponendo diversi oggetti agli script che vengono eseguiti con PythonEngine.ExecuteFile. Espongo loro né conIncorporamento di IronPython, comando di guida incorporato, i miei oggetti CLR
scope.SetVariable("SomeObject", new SomeObject())
o
engine.Execute("from MyNamespace import SomeObject", scope)
a seconda di come gli script li usano. Il mio gruppo di applicazione viene aggiunta al motore con
engine.Runtime.LoadAssembly(Assembly.GetExecutingAssembly())
Ora uno script in grado di eseguire il dump del help(SomeObject)
e piacevole informazioni aiuto poco (*), tuttavia è incompleta. Nessuno degli eventi o proprietà dell'oggetto (pubblico ovviamente) viene visualizzato e molti dei membri "incorporati" risultano mancanti.
Ecco la parte dispari; Se accendo ipy.exe ed eseguo quanto segue:
import sys
sys.path.append('<location of my app>')
import clr
clr.AddReferenceToFile('myapp.exe')
from MyNamespace import SomeObject
help(SomeObject)
Ricevo una discarica diversa, completa con tutti i membri mancanti!
Perché i due differiscono?
Bonus domanda: Supponendo che ho capito di funzionare correttamente, è possibile aggiungere un testo descrittivo sui miei oggetti CLR all'uscita di aiuto()? Come puoi farlo all'interno dello script, sui tuoi tipi nativi di Python? La mia prima ipotesi è stata la DescriptionAttribute, ma non ha funzionato.
(*) Ovviamente uno script di lavoro finale non lo farebbe ma è estremamente utile durante la scrittura/test dello script.
con risposta
Qui è un programma di console completa che illustra come importare il sito che sostituisce l'aiuto interno usless() con l'aiuto della libreria standard di Python().
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;
}
}
Sono stato in grado di verificare che questa risposta sia corretta, tuttavia non sono (finora) in grado di capire come importare site.py in modo programmatico. La mia verifica consisteva nella creazione di ipy.exe (è tutto un semplice file .cs) e provando la procedura ipy sopra. Ottengo i risultati della guida non funzionanti. Se poi metto a disposizione la libreria python standard per questo nuovo ipy.exe, ottengo i risultati della guida corretti. Quindi la soluzione per caricare la libreria standard è sepolta nelle ciotole di Microsoft.Scripting.Hosting o IronPython.Hosting. OO-Spaghetti sarebbe una parola gentile per quel casino. – Tergiver
Ho capito come caricare il modulo del sito e aggiornare la mia domanda sopra. – Tergiver