Benutzerdefinierte IronPython-Importauflösung

7

Ich lade ein IronPython-Skript von einer Datenbank und führe es aus. Dies funktioniert gut für einfache Skripte, aber Importe sind ein Problem. Wie kann ich diese Importaufrufe abfangen und dann die entsprechenden Skripts aus der Datenbank laden?

EDIT: Meine Hauptanwendung ist in C # geschrieben und ich möchte die Aufrufe auf der C # -Seite abfangen, ohne die Python-Skripte zu bearbeiten.

BEARBEITEN: Aus den Recherchen, die ich gemacht habe, sieht es so aus, als ob du deine eigene PlatformAdaptationLayer so erstellst, wie du es dir vorstellen könntest , um dies zu implementieren, aber in diesem Fall funktioniert es nicht. Ich habe meine eigene PAL erstellt und bei meinen Tests wird meine FileExsists -Methode für jeden Import im Skript aufgerufen. Aber aus irgendeinem Grund ruft es niemals eine Überladung der Methode OpenInputFileStream auf. Wenn FileExists durch die IronPython-Quelle gegraben wird und True zurückgegeben wird, versucht es, die Datei selbst auf dem Pfad zu finden. Das sieht also nach einer Sackgasse aus.

    
Dan 05.11.2010, 12:25
quelle

4 Antworten

11

Nach viel Versuch und Irrtum kam ich zu einer Lösung. Ich habe es nie geschafft, dass der PlatformAdaptationLayer -Ansatz richtig funktioniert. Es rief nie zum PAL zurück, wenn versucht wurde, die Module zu laden.

Also habe ich beschlossen, die eingebaute Importfunktion durch die Methode SetVariable zu ersetzen (Engine und Scope sind geschützte Mitglieder, die ScriptEngine und ScriptScope für das Parent-Skript offen legen):

%Vor%

Hoffe das hilft jemandem!

    
Dan 08.11.2010, 20:28
quelle
9

Ich habe nur versucht, dasselbe zu tun, außer dass ich meine Skripte als eingebettete Ressourcen speichern wollte. Ich erstelle eine Bibliothek, die eine Mischung aus C # und IronPython ist und sie als eine einzige DLL verteilen wollte. Ich habe einen PlatformAdaptationLayer geschrieben, der funktioniert, er sucht zuerst in den Ressourcen nach dem Skript, das geladen wird, aber dann greift er auf die Basisimplementierung zurück, die im Dateisystem aussieht. Drei Teile dazu:

Teil 1, Der benutzerdefinierte PlatformAdaptationLayer

%Vor%

Sie müssten die Konstante ResourceScriptsPrefix in den Basis-Namespace ändern, in dem Sie die Python-Skripts gespeichert haben.

Teil 2, Der benutzerdefinierte ScriptHost

%Vor%

Teil 3 schließlich, wie Sie eine Python-Engine mit Ihren benutzerdefinierten Inhalten erhalten:

%Vor%

Es wäre leicht, dies zu ändern, um Skripte von einem anderen Ort, wie einer Datenbank, zu laden. Ändern Sie einfach die Methoden OpenResourceStream, ResourceFileExists und ResourceDirectoryExists.

Hoffe, das hilft.

    
Einar Egilsson 10.01.2011 07:31
quelle
1

Sie können alle I / O-Vorgänge mithilfe der PlatformAdaptationLayer an die Datenbank umleiten. Um dies zu tun, müssen Sie eine ScriptHost implementieren, die die PAL zur Verfügung stellt. Wenn Sie dann die ScriptRuntime erstellen, legen Sie den HostType auf Ihren Hosttyp fest und er wird für die Laufzeit verwendet. Auf der PAL überschreiben Sie dann OpenInputFileStream und geben ein Stream-Objekt mit dem Inhalt aus der Datenbank zurück (Sie könnten hier einfach einen MemoryStream nach dem Lesen aus der DB verwenden).

Wenn Sie immer noch Zugriff auf Datei-I / O bereitstellen möchten, können Sie jederzeit auf "Dateien" von FileStream zurückgreifen, die Sie nicht finden können.

    
Dino Viehland 06.11.2010 03:34
quelle
0

Sie müssen Import-Hooks implementieren. Hier ist eine SO-Frage mit Zeigern: PEP 302 Beispiel: Neue Import-Hooks

    
Ned Batchelder 05.11.2010 12:47
quelle

Tags und Links