Erfahrung mit Pythons "PEP-302 New Import Hooks" [geschlossen]

40

Ich bin einer der Entwickler von Ruby (CRuby). Wir arbeiten an der Veröffentlichung von Ruby 2.0 (geplant für die Veröffentlichung von 2012 / Feb).

Python hat "PEP302: Neue Import-Hooks" (2003):

In diesem PEP wird vorgeschlagen, einen neuen Satz von Import-Hooks hinzuzufügen, mit denen der Python-Importmechanismus besser angepasst werden kann. Im Gegensatz zum aktuellen Import- Hook kann ein Hook neuen Stils in das vorhandene Schema eingefügt werden, wodurch eine genauere Kontrolle darüber möglich ist, wie Module gefunden und geladen werden.

Wir überlegen, eine ähnliche Funktion wie PEP302 in Ruby 2.0 (CRuby 2.0) einzuführen. Ich möchte einen Vorschlag machen, der Matz überzeugen kann. Derzeit kann CRuby Skripte nur aus Dateisystemen auf standardmäßige Weise laden.

Wenn Sie Erfahrungen oder Überlegungen zu PEP 302 haben, teilen Sie diese bitte mit.

Beispiel:

  1. Es ist eine großartige Spezifikation. Keine Notwendigkeit, es zu ändern.
  2. Es ist fast gut, aber es hat dieses Problem ...
  3. Wenn ich bis 2003 zurückkehren könnte, würde ich die Spezifikation ändern auf ...
Koichi Sasada
quelle
6
Wow, der YARV-Typ selbst, hallo und willkommen bei den Programmierern! ;) Bei Stack Exchange mögen wir keine offenen Diskussionen, wir lieben es stattdessen, bestimmte Probleme zu lösen (lesen Sie unsere FAQ kurz durch ). Ich schätze, dies ist der Grund, warum Ihre Frage bei Stack Overflow geschlossen wurde und es bereits eine gibt Abstimmung hier schließen. Sie sollten versuchen, dies ein wenig genauer zu definieren. Haben Sie ein spezielles Anliegen in Bezug auf PEP 302, das diese Frage motiviert hat?
Yannis
4
Vielen Dank für Ihren Kommentar, Yannis. Ich denke, ich möchte über "Software-Architektur" diskutieren. PEP302 scheint ein leistungsfähiges und allgemeines Framework zu sein, um die eigenen Loader für Python-Interpreter zu erweitern. Leistungsstarke Funktionen bergen jedoch das Risiko einer Überbeanspruchung (die magische Codes erzeugt) und verhindern die Optimierung des Interpreters. Daher möchte ich wissen, ob dieses Erweiterungsframework für Python-Benutzer und Interpreter-Entwickler gut oder schlecht geeignet ist . Ich glaube, das Studium der Geschichte wird mir helfen, gute Erfahrungen mit Ruby 2.0 zu machen.
Koichi Sasada
Vielen Dank, dass Sie meine Frage hübsch modifizieren. Und es tut mir leid, wenn diese Frage nicht vorzuziehen ist.
Koichi Sasada
Dies ist ein fantastisches Beispiel dafür, wie eine Frage, die an der Oberfläche erscheint, wenn sie unseren "Meinungsumfragetest" nicht besteht, sich dennoch als erstaunlich wertvoll erweisen kann.
Ross Patterson

Antworten:

47

Ich bin der Maintainer von Pythons Runpy-Modul und einer der Maintainer des aktuellen Importsystems. Obwohl unser Importsystem beeindruckend flexibel ist, würde ich davon abraten, es im Großhandel zu übernehmen, ohne ein paar Änderungen vorzunehmen. Aufgrund von Problemen mit der Abwärtskompatibilität gibt es eine Reihe von Dingen, die umständlicher sind, als sie ansonsten sein müssten.

Eine Sache, die bei PEP 302 in Python wehgetan hat, ist, wie lange es gedauert hat, das Kernimportsystem auf die Verwendung umzustellen. Für den größten Teil eines Jahrzehnts steckte jeder, der irgendetwas Komplexes mit Import-Hooks macht, fest, indem er zwei Teile implementierte: einen, der PEP 302-konforme Loader (wie Zip-Importe) handhabt, und einen zweiten, der den Standard-Importmechanismus auf Dateisystembasis handhabt. Erst in der kommenden Version 3.3 kümmert sich der Umgang mit PEP 302-Ladern auch um den Umgang mit Modulen, die über den Standard-Dateisystem-Importmechanismus importiert wurden. Versuchen Sie, diesen Fehler nicht zu wiederholen, wenn Sie ihn möglicherweise vermeiden können.

PEP 420 (für Python 3.3 implementiert) nimmt einige Ergänzungen zum Protokoll vor, damit Importeure Teile zu Namespace-Paketen beisteuern können. Es behebt auch ein Namensproblem in der Finder-API-Definition (wodurch das falsch benannte "find_module" durch das genauere "find_loader" ersetzt wird). Dies sollte hoffentlich alles klarer in der Sprachspezifikation dokumentiert sein, wenn 3.3rc1 in ein paar Wochen erscheint.

Ein weiteres bemerkenswertes Problem besteht darin, dass der in PEP 302 spezifisch dokumentierte Ansatz einen viel zu hohen globalen Prozessstatus aufweist. Folgen Sie uns nicht auf diesem Weg - versuchen Sie, den Zustand in einem kohärenteren Objektmodell zu kapseln, damit es ein wenig einfacher ist, andere Module selektiv zu importieren (C-Erweiterungsmodule sind der Fluch, um eine solche Kapselung vollständig wirksam zu machen, aber auch auf einer bestimmten Ebene der Kapselung kann hilfreich sein).

In PEP 406 (http://www.python.org/dev/peps/pep-0406/) wird eine mögliche rückwärtskompatible Weiterentwicklung des Python-Ansatzes mit verbesserter Statuskapselung erörtert. Wenn Sie jedoch von Anfang an über ein gekapseltes Statusmodell verfügen, können Sie Ihre APIs entsprechend definieren und vermeiden, dass Importer und Loader überhaupt auf den globalen Status zugreifen (stattdessen wird ein Verweis auf die aktive Engine übergeben).

Ein weiteres fehlendes Element in PEP 302 ist die Möglichkeit, einen Importeur nach einem Iterator für die von diesem Importeur bereitgestellten Module zu fragen (dies ist beispielsweise für Freeze-Dienstprogramme und Dienstprogramme für die automatische Dokumentation erforderlich, mit denen Docstrings extrahiert werden). Da es unglaublich nützlich ist, ist es wahrscheinlich besser, es von Anfang an zu standardisieren: http://docs.python.org/dev/library/pkgutil#pkgutil.iter_modules (wir werden es wahrscheinlich endgültig zu einem formal festgelegten Modul machen) API in Python 3.4)

Und mein letzter Kommentar ist, dass Sie sich die Aufteilung der Zuständigkeiten zwischen dem Importsystem und den Ladeobjekten genauer ansehen sollten. Erwägen Sie insbesondere, die API "load_module" in separate Schritte "init_module" und "exec_module" zu unterteilen. Dies sollte es Ihnen ermöglichen, das Ausmaß zu minimieren, in dem Lader direkt mit dem Importstatus interagieren müssen.

PEP 302 und importlib sind ein guter Ausgangspunkt für ein flexibleres Importsystem, aber es gibt definitiv Fehler, die wir gemacht haben und die es wert sind, vermieden zu werden.

ncoghlan
quelle
1
Sie sind nicht ganz noch fertig, aber ein erster Entwurf der vollständigen Importsystem docs finden Sie unter docs.python.org/dev/reference/import
ncoghlan
1
python.org/dev/peps/pep-0451 ist ein Update von Pythons Importsystem für Python 3.4, das viele der Kommentare von Brett und mir hier anspricht.
ncoghlan
28

Neben ncoghlan bin ich der andere Betreuer von Pythons Importsystem und der Autor der aktuellen Implementierung, importlib (http://docs.python.org/dev/py3k/library/importlib.html). Alles, was Nick gesagt hat, dass ich damit einverstanden bin, deshalb möchte ich nur ein paar zusätzliche Informationen hinzufügen.

Verlassen Sie sich zunächst nicht zu stark auf PEP 302, sondern schauen Sie sich stattdessen an, was die importlib in Bezug auf abstrakte Basisklassen usw. bietet. Aus Gründen der Abwärtskompatibilität mussten die Dinge mit PEP 302 kompatibel sein, aber ich musste einige meiner hinzufügen eigene APIs, um die Unterstützung für echte Flexibilität zu vervollständigen.

Ein weiterer wichtiger Punkt ist, dass Sie Entwicklern zwei Möglichkeiten der Flexibilität einräumen. Eine ist die Möglichkeit, Code nicht nur direkt im Dateisystem als einzelne Dateien zu speichern (ich bezeichne dies als Speicher-Backend für Importe), z. B. damit Code in einer Zip-Datei, einer SQLite-Datenbank usw. Gespeichert werden kann Die andere Unterstützung besteht darin, die Steuerung in irgendeiner Weise Code vor oder nach der Verarbeitung zuzulassen, z Eine Variable wäre viel einfacher zu unterstützen.

Während Letzteres nur selten benötigt wird, müssen Sie sich bei Ersterem um die Unterstützung kümmern. Und hier definieren Sie die Interaktions-APIs für Dateisysteme praktisch neu. Da einige Leute Assets benötigen, die als Dateien mit ihrem Code gespeichert sind, müssen Sie eine gute Möglichkeit zum Lesen von Dateien, Erkennen von Dateien usw. bereitstellen. Wir müssen weiterhin den Teil der API implementieren, um herauszufinden, welche Datendateien verfügbar sind, sie aufzulisten usw .

Dann brauchen Sie aber auch codespezifische APIs. Wie Nick bereits erwähnt hat, benötigen Sie APIs, um herauszufinden, welche Module ein Paket usw. enthält, die nicht dateispezifisch sind. Es gibt diese seltsame Dualität, APIs für den Umgang mit Modulen zu haben, bei denen Sie das Konzept von Dateien entfernt haben, aber dann müssen Sie APIs bereitstellen, um auf dateiähnliche Asset-Daten zuzugreifen. Und sobald Sie versuchen, eines in Bezug auf das andere umzusetzen, um eine Verdoppelung zu vermeiden, wird das Wasser sehr trübe (dh die Leute verlassen sich am Ende auf die erwartete Dateipfadstrukturierung usw., ohne zu beachten, dass der Pfad möglicherweise kein echter Pfad ist weil es sich um eine zip-Datei handelt, die Code und nicht nur eine Datei enthält). IOW werden Sie am Ende zwei ähnliche APIs implementieren müssen, aber langfristig sind Sie besser dran.

Wie Nick sagte, ist unsere Lösung ein guter Ausgangspunkt, aber es ist nicht so, wie ich es heute tun würde, wenn ich die API von Grund auf neu entwerfen würde.

Brett Cannon
quelle
-1

Mit PEP 302 können Sie sich in den Python-Importmechanismus einbinden, was bedeutet, dass Sie Code aus anderen Quellen wie Datenbanken, ZIP-Dateien usw. importieren können.

Bei der Python-Implementierung von Importen gibt es eine lange Geschichte der Komplexität, die erst in Kürze durch die Einführung einer Python-Implementierung von Import vereinfacht wird.

Ich sollte raten, lange und gründlich über die Eckfälle nachzudenken. Dann erhalten Sie wahrscheinlich eine nützliche Implementierung.

Holdenweb
quelle