9
votes

Résolution d'importation personnalisée Ironthon

Je charge un script IronPython à partir d'une base de données et l'exécutant. Cela fonctionne bien pour des scripts simples, mais les importations sont un problème. Comment puis-je intercepter ces appels d'importation, puis charger les scripts appropriés de la base de données?

Edit: Ma principale application est écrite en C # et j'aimerais intercepter les appels sur le côté C # sans modifier les scripts Python.

Edit: de la recherche que j'ai faite, on dirait que la création de votre propre plate-formeAdaptationLayer est la façon dont vous êtes supposé pour la mettre en œuvre, mais cela ne fonctionne pas dans ce cas. J'ai créé mon propre copain et dans mes tests, mon FileExSIST est appelé à chaque importation dans le script. Mais pour une raison quelconque, il n'appelle jamais une surcharge de la méthode OpenInputFileStream . Creuser par la source Ironpython, une fois que les FileExists reviennent true, il essaie de localiser le fichier lui-même sur le chemin. Donc cela ressemble à une impasse.


0 commentaires

4 Réponses :


0
votes

Vous devez mettre en œuvre des crochets d'importation. Voici une question si question avec les pointeurs: EPP 302 Exemple: Nouveaux crochets d'importation


2 commentaires

Je ne sais pas si j'étais assez clair dans mon phrasé original de la question. L'application appelant le script Python est écrite en C # et je souhaite traiter le script Python comme une boîte noire autant que possible, de sorte que j'aimerais pouvoir intercepter les importations sur le côté C # si possible. J'ai édité la question initiale pour refléter ces informations supplémentaires.


Voir au dessus. Cela ressemble à cela devrait fonctionner, mais ce n'est pas le cas. Peut-être que la mise en œuvre de l'importation IronPython enfreint l'approche standard?



1
votes

Vous pouvez rétablir tous les E / S à la base de données à l'aide de la plate-formeAdapaPaptationLayer. Pour ce faire, vous devrez mettre en œuvre un scriptthost qui fournit le PAL. Ensuite, lorsque vous créez le scripttruntime, vous définissez le fichier HostType sur votre type d'hôte et que ce sera utilisé pour l'exécution. Sur la copie, vous remplacez ensuite OpenInputFileStream et renvoyez un objet de flux qui possède le contenu de la base de données (vous pouvez simplement utiliser une mémoire Morthstream ici après la lecture de la DB).

Si vous souhaitez toujours fournir un accès aux fichiers E / S, vous pouvez toujours revenir à FileStream pour "fichiers" que vous ne trouvez pas.


4 commentaires

Je travaille sur une solution qui l'utilise comme point de départ (j'ai trouvé des éléments utiles dispersés sur ( efreedom.com/question/1-3264029/... et mail-archive.com/users@lists.ironpython.com/msg06080.html semble être déchiffrer comment les différentes méthodes de couche d'adaptation de la plate-forme obtiennent Appelé. Je ne peux pas sembler trouver de la documentation sur ce tout.


L'hôte Silverlight peut être un exemple raisonnable de la manière de faire cela si vous souhaitez voir une implémentation existante.


Voir ma réponse pour une plate-forme personnalisée assez simple.


Cette approche semble utile si vous voulez simplement avoir les fichiers stockés quelque part que l'emplacement de système de fichiers attendu, mais pas si vous le souhaitez, dites, précompiler les.



10
votes

Après beaucoup d'essais et d'erreurs, je suis arrivé à une solution. Je n'ai jamais réussi à obtenir l'approche plateformeAphapTationnayer pour fonctionner correctement. Il n'a jamais rappelé au PAL lorsque vous essayez de charger les modules.

Donc, de sorte que j'ai décidé de faire était de remplacer la fonction d'importation intégrée à l'aide de la méthode SETVARIABLE, comme indiqué ci-dessous (moteur et périmètre sont des membres protégés exposant le Scriptengine et scriptscope pour le script parent): xxx

espère que cela aide quelqu'un!


1 commentaires

Merci! J'ai exactement le même cas d'utilisation que le vôtre.



10
votes

J'essayais juste de faire la même chose, sauf que je voulais stocker mes scripts comme des ressources intégrées. Je crée une bibliothèque qui est un mélange de C # et IronPython et je voulais le distribuer en tant que DLL unique. J'ai écrit une plate-formeAborateAdaptationLayer qui fonctionne, il examine d'abord les ressources du script chargé, mais redevient ensuite à la mise en œuvre de la base qui regarde dans le système de fichiers. Trois parties à ceci:

Partie 1, la plate-forme personnaliséeAdaptionnationLayer P>

namespace ZenCoding.Hosting
{
    internal static class ResourceAwareScriptEngineSetup
    {
        public static ScriptEngine CreateResourceAwareEngine()
        {
            var setup = Python.CreateRuntimeSetup(null);
            setup.HostType = typeof(ResourceAwareScriptHost);
            var runtime = new ScriptRuntime(setup);
            return runtime.GetEngineByTypeName(typeof(PythonContext).AssemblyQualifiedName);
        }
    }
}


4 commentaires

Pourriez-vous ajouter quelle version de IronPython c'était pour? Je pense que c'était pour une version plus ancienne que IronPython 2.7?


Oui, c'était il y a deux ans, quelle que soit la version actuelle. Probablement 2.6, mais je ne suis pas sûr.


Y a-t-il une meilleure façon de 2,7 ans? Ce qui précède fonctionne toujours BTW.


@simonjpascoe, j'ai essayé d'expliquer deux autres approches de Cette réponse .