2011-01-08 9 views
10

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

risposta

4

La mia ipotesi è che nella tua app non importi la libreria standard. IronPython include una funzione di guida integrata e la libreria standard include una funzione di guida che viene installata da site.py. Se si assicura che la libreria standard sia disponibile quando si ospita e quindi si importa site.py quando si crea il motore, è necessario ottenere la guida della libreria standard. Detto questo è probabilmente un bug o una funzionalità mancante che l'aiuto integrato non sta documentando eventi e proprietà.

Per quanto riguarda la documentazione, si, è sufficiente utilizzare i commenti di C# e creare con l'opzione /doc:MyAssemblyName.xml. Se il file XML si trova nella stessa directory dell'assembly, IronPython leggerà le stringhe doc e le fornirà per gli attributi doc che help() quindi legge.

+0

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

+0

Ho capito come caricare il modulo del sito e aggiornare la mia domanda sopra. – Tergiver