Heim Backend-Entwicklung Python-Tutorial Ein Dolmetscher in einem Dolmetscher

Ein Dolmetscher in einem Dolmetscher

Dec 15, 2024 pm 08:22 PM

An interpreter inside an interpreter

Ein paar Monate nach Beginn der Entwicklung beschloss ich, dass mein Nordstern für Memphis darin bestehen würde, einen Flask-Server vollständig in meinem Interpreter zu betreiben. Ich hatte keine Ahnung, wie viel Arbeit das mit sich bringen würde, nur, dass es cool klang und mir auf dem Weg wahrscheinlich viel beibringen würde. Wenn ich dieses Ziel heute erreichen würde, würde ich mich vielleicht für FastAPI entscheiden oder gar nichts, weil das dumm von mir war.

Python-Stdlib

Eine große Entscheidung, die ich treffen musste, war, wie ich mit der Python-Standardbibliothek umgehen sollte. Wie Sie wahrscheinlich wissen, ist die Standardbibliothek einer Sprache technisch gesehen nicht Teil der Sprachdefinition oder Laufzeit. Es ist in Veröffentlichungen enthalten, um die Sprache und Laufzeit nützlicher zu machen. Stellen Sie sich Python ohne Threading oder Async-Unterstützung vor. Sie könnten immer noch Ausdrücke auswerten und Klassen instanziieren, aber die meisten produktionsbereiten Programme benötigen eine Art Parallelitätsunterstützung.

Eine Möglichkeit wäre, die gesamte Standardbibliothek selbst neu zu schreiben. Ich baue einen Dolmetscher, nicht wahr? Ich glaube, dass dies der Ansatz von RustPython ist, ein bewundernswerter Weg. Ich dachte, ich hätte genug damit zu tun, die Laufzeit zum Laufen zu bringen, suchte nach allen möglichen Abstrichen und habe mich dagegen entschieden.

Die Python-Standardbibliothek besteht aus zwei Hauptteilen: den in Python implementierten Teilen und den in C implementierten Teilen. Praktischerweise hatte ich meinen eigenen Python-Interpreter. Könnte ich einfach die Python-Quelldatei vom Host-Rechner interpretieren, um Ersteres zu erfüllen? Ja, das könnte ich. Ich müsste jede verwendete Syntax und Funktion unterstützen, aber danach würde es einfach funktionieren.

Im C-Teil wird es interessant. Damals, im Jahr 2023, habe ich beschlossen, einen Python-Interpreter in meinen Python-Interpreter einzubetten, ohne vollständig zu verstehen, was das bedeutet. Jetzt war es an der Zeit, mich damit auseinanderzusetzen und zu entscheiden, ob ich bei diesem Ansatz bleiben oder einen anderen Weg wählen wollte.

Der Interop-Shop für Rust und Python ist Pyo3. Als einziges Spiel in der Stadt nutzt Pyo3 das Foreign Function Interface (FFI), damit Ihr Rust-Code Aufrufe in die CPython-Binärdatei tätigen kann. Dies funktioniert durch die Einigung auf das Application Binary Interface (ABI), ein Konzept, das ich während meiner Karriere bei AMD verwendet habe. Kernsoftware ftw!

Module importieren

Mein erster Anwendungsfall bestand darin, import sys auszuführen und mir dadurch ein Objekt zu geben, für das ich einen Mitgliedszugriffsvorgang durchführen konnte. Ich beginne hier mit der Dolmetschersprache, aber das ist die Art von REPL-Sitzung, von der ich spreche.

Python 3.12.5 (main, Aug  6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.3.9.4)]
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys
<module 'sys' (built-in)>
>>> type(sys.modules)
<class 'dict'>
Nach dem Login kopieren
Nach dem Login kopieren

Diese Funktionalität mit Pyo3 zu erhalten war unkompliziert.

pub struct CPythonModule(PyObject);

impl CPythonModule {
    pub fn new(name: &str) -> Self {
        pyo3::prepare_freethreaded_python();
        let pymodule = Python::with_gil(|py|
            PyModule::import(py, name).expect("Failed to import module").into()
        );

        Self(pymodule)
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Und wir können dies nutzen, um eine ähnliche REPL-Sitzung in Memphis durchzuführen, vorausgesetzt, Sie erinnern sich an den Cocktail an Funktionsflags, um dies zum Laufen zu bringen.

Python 3.12.5 (main, Aug  6 2024, 19:08:49) [Clang 15.0.0 (clang-1500.3.9.4)]
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys
<module 'sys' (built-in)>
>>> type(sys.modules)
<class 'dict'>
Nach dem Login kopieren
Nach dem Login kopieren

Wenn Sie sich fragen: Könnten Sie nicht einfach diesen Ansatz verwenden, um die gesamte Standardbibliothek (einschließlich der in Python und C geschriebenen Teile) zu importieren und Ihr gesamtes Leben, Ihre Freiheit und das Streben nach Glück einfacher zu machen? Die Antwort ist ja. Das wäre ein gültiger Ansatz! Allerdings würde das meinen Interpreter mehr zu einer Hülle um CPython machen, als mir lieb ist. Dies ist eine Lernübung, daher bin ich für willkürliche Entscheidungen. Für die Puristen da draußen, die sagen, dass das Laden irgendeines CPython-Teils in Memphis Memphis zu keinem echten Interpreter macht, würde ich nur sagen: Bitte zeigen Sie mir Ihren Interpreter.

Ich habe einen Schnelltest mit htop durchgeführt, indem ich import sys innerhalb einer REPL-Sitzung mit Memphis und CPython ausgeführt habe. Da dadurch auf Memphis die CPython-Bibliotheken in den Speicher geladen werden, erhöhte sich die RAM-Nutzung (Resident Set Size in htop) um etwa 5 MB. Zum Vergleich: Die Memphis REPL nach dem Laden des SYS-Moduls verbraucht etwa 9 MB RAM, während die Python REPL vor und nach dem Laden des SYS-Moduls etwa gleich viel RAM verbraucht. Ich bin mir sicher, dass dies kein Vergleich von Äpfeln zu Äpfeln ist, aber es zeigte mir zumindest, dass Memphis meinen Computer nicht langsam ersticken würde.

Objekte umwandeln und existenziell werden

Die nächste Komplexität bei diesem Setup besteht darin, meine Memphis-Objektdarstellung in CPython-Darstellungen zu konvertieren und umgekehrt. Dies ist ein Work-in-Progress und meine Hauptanweisung war zunächst „Nicht scheitern“ und in jüngerer Zeit „Warnungen anzeigen, wenn Sie eine verlustbehaftete Konvertierung durchführen.“

Hier ist meine Konvertierung von einem PyObject, das die Objektdarstellung auf der Pyo3-Seite ist, in ein ExprResult, meine Memphis-Darstellung.

pub struct CPythonModule(PyObject);

impl CPythonModule {
    pub fn new(name: &str) -> Self {
        pyo3::prepare_freethreaded_python();
        let pymodule = Python::with_gil(|py|
            PyModule::import(py, name).expect("Failed to import module").into()
        );

        Self(pymodule)
    }
}
Nach dem Login kopieren
Nach dem Login kopieren

Und hier ist der umgekehrte Vergleich. Beachten Sie, dass wir für beides ein Python-Objekt übergeben müssen, das unseren Zugriff auf die CPython-GIL (globale Interpretersperre) steuert.

memphis 0.1.0 REPL (Type 'exit()' to quit)
>>> import sys
>>> sys
<module 'sys' (built-in)>
>>> type(sys.modules)
<class 'dict' (built-in)>
Nach dem Login kopieren

Dies ist ein reichhaltiges Gebiet, das ich gerne weiter erforschen würde. Hier sind einige der Richtungen, die ich in Betracht gezogen habe:

  1. Konvertieren Sie jedes Mal, wenn ein Objekt die FFI-Schnittstelle überschreitet. (Und ja, mir ist klar, dass sich das Akronym auf „Fremdfunktionsschnittstelle“ erweitern lässt.) Das ist ungefähr das, was ich bereits mache, ich müsste es nur besitzen und darf mich nicht wie ein Betrüger fühlen. Das könnte einfach, aber ineffizient sein.
  2. Führen Sie eine Registrierung, sodass jedes Objekt auf jeder Seite höchstens einmal vorhanden ist. Dies wäre effizienter als (1), aber es würde einen stabilen Wert erfordern, den Sie zum Suchen und Verknüpfen dieser Objekte verwenden könnten.
  3. Streben Sie eine einzelne Darstellung auf der Rust-Seite an und verwenden Sie Pyo3 als Proxy und träge Konvertierung von Feldern nach Bedarf. Ich glaube, dass dies immer noch die Funktionalität von (1) nutzen würde, aber auf effizientere Weise.
  4. Stellen Sie sicher, dass das Speicherlayout eines Memphis-Objekts dem eines PyObject entspricht. Ähnlich wie #[repr(C)] bereits in Rust funktioniert, ähnelt dies der Rolle, die ein ABI für einen Funktionsaufruf spielt. Ich bin mir nicht einmal sicher, ob dies möglich ist, da jede Seite unterschiedlich für ihre Bewertung benötigt, aber das fasziniert mich.

Ich übertreibe es, weil ich im Moment kaum ein C-Modul laden kann, aber meine Neugier in diesem Bereich ist wirklich grenzenlos.

Das Ende

Ich beschäftige mich weiterhin damit, als ich auf einen neuen Konvertierungsfehler stoße, während ich mich auf den Weg mache, Flask zum Booten zu bringen. Diese Übung ist eine gute Erinnerung daran, dass alle Objekte (oder Klassen, Module usw.) eine Reihe von Attributen sind, die in einem bekannten Format im Speicher vorhanden sind. Wenn wir dieses Format gut genug verstehen, sollten wir in der Lage sein, unglaubliche Dinge zu tun, unabhängig davon, ob es sich um Memphis oder CPython handelt.

Diese Philosophie treibt auch meine Arbeit mit From Scratch Code an. Wenn Sie es satt haben, eine Bibliothek nicht in Ihrem Code zum Laufen zu bringen, empfehle ich Ihnen, einen Schritt zurückzutreten und zu fragen: Was macht die Bibliothek eigentlich? Benötigen Sie es oder könnte eine einfachere Lösung funktionieren? Ich glaube daran, diese Neugier auf Software zu wecken – und ich helfe Ihnen gerne dabei, diese Denkweise in Ihren Werkzeugkasten zu integrieren.


Wenn Sie weitere Beiträge dieser Art direkt in Ihrem Posteingang erhalten möchten, können Sie sich hier anmelden!

Anderswo

Neben der Betreuung von Software-Ingenieuren schreibe ich auch über meine Erfahrungen als Erwachsener, bei dem Autismus diagnostiziert wurde. Weniger Code und die gleiche Anzahl an Witzen.

  • Warum sehne ich mich nach Anerkennung? - Von Scratch Dot org

Das obige ist der detaillierte Inhalt vonEin Dolmetscher in einem Dolmetscher. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heißer Artikel

<🎜>: Bubble Gum Simulator Infinity - So erhalten und verwenden Sie Royal Keys
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Nordhold: Fusionssystem, erklärt
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Mandragora: Flüstern des Hexenbaum
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen

Java-Tutorial
1666
14
PHP-Tutorial
1273
29
C#-Tutorial
1252
24
Python vs. C: Anwendungen und Anwendungsfälle verglichen Python vs. C: Anwendungen und Anwendungsfälle verglichen Apr 12, 2025 am 12:01 AM

Python eignet sich für Datenwissenschafts-, Webentwicklungs- und Automatisierungsaufgaben, während C für Systemprogrammierung, Spieleentwicklung und eingebettete Systeme geeignet ist. Python ist bekannt für seine Einfachheit und sein starkes Ökosystem, während C für seine hohen Leistung und die zugrunde liegenden Kontrollfunktionen bekannt ist.

Python: Spiele, GUIs und mehr Python: Spiele, GUIs und mehr Apr 13, 2025 am 12:14 AM

Python zeichnet sich in Gaming und GUI -Entwicklung aus. 1) Spielentwicklung verwendet Pygame, die Zeichnungen, Audio- und andere Funktionen bereitstellt, die für die Erstellung von 2D -Spielen geeignet sind. 2) Die GUI -Entwicklung kann Tkinter oder Pyqt auswählen. Tkinter ist einfach und einfach zu bedienen. PYQT hat reichhaltige Funktionen und ist für die berufliche Entwicklung geeignet.

Python vs. C: Lernkurven und Benutzerfreundlichkeit Python vs. C: Lernkurven und Benutzerfreundlichkeit Apr 19, 2025 am 12:20 AM

Python ist leichter zu lernen und zu verwenden, während C leistungsfähiger, aber komplexer ist. 1. Python -Syntax ist prägnant und für Anfänger geeignet. Durch die dynamische Tippen und die automatische Speicherverwaltung können Sie die Verwendung einfach zu verwenden, kann jedoch zur Laufzeitfehler führen. 2.C bietet Steuerung und erweiterte Funktionen auf niedrigem Niveau, geeignet für Hochleistungsanwendungen, hat jedoch einen hohen Lernschwellenwert und erfordert manuellem Speicher und Typensicherheitsmanagement.

Python und Zeit: Machen Sie das Beste aus Ihrer Studienzeit Python und Zeit: Machen Sie das Beste aus Ihrer Studienzeit Apr 14, 2025 am 12:02 AM

Um die Effizienz des Lernens von Python in einer begrenzten Zeit zu maximieren, können Sie Pythons DateTime-, Zeit- und Zeitplanmodule verwenden. 1. Das DateTime -Modul wird verwendet, um die Lernzeit aufzuzeichnen und zu planen. 2. Das Zeitmodul hilft, die Studie zu setzen und Zeit zu ruhen. 3. Das Zeitplanmodul arrangiert automatisch wöchentliche Lernaufgaben.

Python vs. C: Erforschung von Leistung und Effizienz erforschen Python vs. C: Erforschung von Leistung und Effizienz erforschen Apr 18, 2025 am 12:20 AM

Python ist in der Entwicklungseffizienz besser als C, aber C ist in der Ausführungsleistung höher. 1. Pythons prägnante Syntax und reiche Bibliotheken verbessern die Entwicklungseffizienz. 2. Die Kompilierungsmerkmale von Compilation und die Hardwarekontrolle verbessern die Ausführungsleistung. Bei einer Auswahl müssen Sie die Entwicklungsgeschwindigkeit und die Ausführungseffizienz basierend auf den Projektanforderungen abwägen.

Welches ist Teil der Python Standard Library: Listen oder Arrays? Welches ist Teil der Python Standard Library: Listen oder Arrays? Apr 27, 2025 am 12:03 AM

PythonlistsarePartThestandardlibrary, whilearraysarenot.listarebuilt-in, vielseitig und UNDUSEDFORSPORINGECollections, während dieArrayRay-thearrayModulei und loses und loses und losesaluseduetolimitedFunctionality.

Python: Automatisierung, Skript- und Aufgabenverwaltung Python: Automatisierung, Skript- und Aufgabenverwaltung Apr 16, 2025 am 12:14 AM

Python zeichnet sich in Automatisierung, Skript und Aufgabenverwaltung aus. 1) Automatisierung: Die Sicherungssicherung wird durch Standardbibliotheken wie OS und Shutil realisiert. 2) Skriptschreiben: Verwenden Sie die PSUTIL -Bibliothek, um die Systemressourcen zu überwachen. 3) Aufgabenverwaltung: Verwenden Sie die Zeitplanbibliothek, um Aufgaben zu planen. Die Benutzerfreundlichkeit von Python und die Unterstützung der reichhaltigen Bibliothek machen es zum bevorzugten Werkzeug in diesen Bereichen.

Python lernen: Ist 2 Stunden tägliches Studium ausreichend? Python lernen: Ist 2 Stunden tägliches Studium ausreichend? Apr 18, 2025 am 12:22 AM

Ist es genug, um Python für zwei Stunden am Tag zu lernen? Es hängt von Ihren Zielen und Lernmethoden ab. 1) Entwickeln Sie einen klaren Lernplan, 2) Wählen Sie geeignete Lernressourcen und -methoden aus, 3) praktizieren und prüfen und konsolidieren Sie praktische Praxis und Überprüfung und konsolidieren Sie und Sie können die Grundkenntnisse und die erweiterten Funktionen von Python während dieser Zeit nach und nach beherrschen.

See all articles