Ich frage mich nur (jetzt, wo ich mit C ++ angefangen habe, das einen Compiler benötigt), warum Python keinen Compiler benötigt.
Ich gebe einfach den Code ein, speichere ihn als Exec und führe ihn aus. In C ++ muss ich Builds und all das andere lustige Zeug machen.
python
interpretieren Sie die .py-Datei mit dem Befehl, oder wenn Sie IDLE oder Eclipse verwenden, erledigt die IDE dies für Sie.Antworten:
Python hat einen Compiler! Man merkt es einfach nicht, weil es automatisch läuft. Sie können jedoch feststellen, dass es vorhanden ist: Sehen Sie sich die Dateien an
.pyc
(oder.pyo
prüfen Sie, ob das Optimierungsprogramm aktiviert ist), die für die von Ihnen erstellten Module erstellt wurdenimport
.Außerdem wird es nicht mit dem Code des nativen Computers kompiliert. Stattdessen wird ein Bytecode kompiliert, der von einer virtuellen Maschine verwendet wird. Die virtuelle Maschine selbst ist ein kompiliertes Programm. Dies ist der Funktionsweise von Java sehr ähnlich. In der Tat so ähnlich, dass es eine Python-Variante ( Jython ) gibt, die stattdessen mit dem Byte-Code der Java Virtual Machine kompiliert wird! Es gibt auch IronPython , das mit Microsofts CLR (von .NET verwendet) kompiliert wird. (Der normale Python-Bytecode-Compiler wird manchmal als CPython bezeichnet, um ihn von diesen Alternativen zu unterscheiden.)
C ++ muss seinen Kompilierungsprozess offenlegen, da die Sprache selbst unvollständig ist. Es gibt weder alles an, was der Linker wissen muss, um Ihr Programm zu erstellen, noch können Kompilierungsoptionen portabel angegeben werden (einige Compiler lassen dies zu
#pragma
, aber das ist kein Standard). Also musst du den Rest der Arbeit mit Makefiles und möglicherweise Auto Hell (autoconf / automake / libtool) machen. Dies ist wirklich nur ein Überbleibsel von dem, was C getan hat. Und C hat es so gemacht, weil es den Compiler einfach gemacht hat, was ein Hauptgrund dafür ist, dass er so beliebt ist (jeder konnte in den 80ern einen einfachen C-Compiler entwickeln).Einige Dinge, die sich auf den Compiler- oder Linker-Betrieb auswirken können, jedoch nicht in der C- oder C ++ - Syntax angegeben sind:
Einige davon können erkannt, aber nicht angegeben werden. Ich kann z. B. feststellen, welches C ++ verwendet wird
__cplusplus
, aber ich kann nicht angeben, dass C ++ 98 für meinen Code innerhalb des Codes selbst verwendet wird. Ich muss es als Flag an den Compiler im Makefile übergeben oder eine Einstellung in einem Dialog vornehmen.Während Sie vielleicht denken, dass im Compiler ein "Abhängigkeitsauflösungssystem" existiert, das automatisch Abhängigkeitsdatensätze generiert, geben diese Datensätze nur an, welche Header-Dateien eine bestimmte Quelldatei verwendet. Sie können nicht angeben, welche zusätzlichen Quellcodemodule zum Verknüpfen mit einem ausführbaren Programm erforderlich sind, da es in C oder C ++ keine Standardmethode gibt, die angibt, dass eine bestimmte Headerdatei die Schnittstellendefinition für ein anderes Quellcodemodul ist, und nicht nur eine Reihe von Zeilen, die an mehreren Stellen angezeigt werden sollen, damit Sie sich nicht wiederholen. Es gibt Traditionen in Dateinamenskonventionen, aber diese sind dem Compiler und Linker nicht bekannt oder werden von ihm nicht erzwungen.
Einige davon können mit eingestellt werden
#pragma
, aber dies ist kein Standard, und ich habe vom Standard gesprochen. All diese Dinge könnten durch eine Norm spezifiziert werden, waren jedoch nicht im Interesse der Abwärtskompatibilität. Die vorherrschende Weisheit ist, dass Makefiles und IDEs nicht kaputt sind, also reparieren Sie sie nicht.Python erledigt dies alles in der Sprache. Gibt beispielsweise
import
eine explizite Modulabhängigkeit an, impliziert den Abhängigkeitsbaum und Module werden nicht in Header- und Quelldateien (dh Schnittstelle und Implementierung) aufgeteilt.quelle
Python ist eine interpretierte Sprache. Dies bedeutet, dass sich auf Ihrem Computer Software befindet, die den Python-Code liest und die "Anweisungen" an den Computer sendet. Der Wikipedia-Artikel zu interpretierten Sprachen könnte von Interesse sein.
Wenn eine Sprache wie C ++ (eine kompilierte Sprache) kompiliert wird, bedeutet dies, dass sie in Maschinencode konvertiert wird, der bei der Ausführung direkt von der Hardware gelesen wird. Der Wikipedia - Artikel über kompilierten Sprachen könnte einen interessanten Kontrast.
quelle
Nicht alle kompilierten Sprachen verfügen über einen direkten Bearbeitungszyklus zum Kompilieren von Links.
Worauf Sie stoßen, ist eine Funktion / Einschränkung von C ++ (oder zumindest von C ++ - Implementierungen).
Um etwas zu tun, müssen Sie Ihren Code in Dateien speichern und ein monolithisches Image durch einen Prozess namens Verknüpfen erstellen.
Insbesondere ist es dieser monolithische Verknüpfungsprozess, der mit der Unterscheidung zwischen Kompilieren und Interpretieren verwechselt wird.
Einige Sprachen erledigen all diese Dinge viel dynamischer, indem sie den unbeholfenen monolithischen Verknüpfungsschritt eliminieren und nicht das Kompilieren in Maschinencode. Der Quellcode wird weiterhin zu Objektdateien kompiliert, diese werden jedoch in ein Laufzeitabbild geladen, anstatt in eine monolithische ausführbare Datei verknüpft zu werden.
Sie sagen "reload this module", und es lädt die Quelle und interpretiert sie oder kompiliert sie, abhängig von einem Modusschalter.
Die Linux-Kernel-Programmierung weist einige dieser Merkmale auf, obwohl Sie in C arbeiten. Sie können ein Modul neu kompilieren und laden und entladen. Natürlich ist Ihnen immer noch klar, dass Sie eine ausführbare Datei produzieren, und diese wird von einem komplexen Build-System verwaltet, das noch einige manuelle Schritte enthält. Fakt ist jedoch, dass Sie letztendlich nur dieses kleine Modul entladen und neu laden können und nicht den gesamten Kernel neu starten müssen.
Einige Sprachen weisen eine noch feinkörnigere Modularisierung auf, und das Erstellen und Laden erfolgt innerhalb ihrer Laufzeit, sodass es nahtloser ist.
quelle
Was für eine Ablenkung von der ursprünglichen Frage ... Ein Punkt, der nicht erwähnt wird, ist, dass die Quelle eines Python-Programms das ist, was Sie verwenden und verbreiten. Aus Sicht des Benutzers ist es das Programm. Wir tendieren dazu, Dinge in Kategorien zu vereinfachen, die nicht gut definiert sind.
Kompilierte Programme werden normalerweise als eigenständige Dateien mit Maschinencode betrachtet. (Zugegebenermaßen häufig mit Links zu dynamischen Linkbibliotheken, die mit bestimmten Betriebssystemen verknüpft sind). Dies sagte ... es gibt Variationen der meisten Programmiersprachen, die als kompiliert oder interpretiert beschrieben werden könnten.
Python benötigt keinen Compiler, da es sich auf eine Anwendung (einen so genannten Interpreter) stützt, die den Code kompiliert und ausführt, ohne den erstellten Maschinencode in einer Form zu speichern, auf die Sie problemlos zugreifen oder die Sie verteilen können.
quelle
Alle Programmiersprachen erfordern die Übersetzung von menschlichen Konzepten in einen Zielmaschinencode. Sogar die Assemblersprache muss in Maschinencode übersetzt werden. Diese Übersetzung findet normalerweise in den folgenden Phasen statt:
Phase 1: Analyse und Übersetzung (Parsing) in einen Zwischencode. Phase 2: Übersetzung des Zwischencodes in Zielmaschinencode mit Platzhaltern für externe Referenzen. Phase 3: Auflösung der externen Referenzen und Verpackung in ein maschinenausführbares Programm.
Diese Übersetzung wird häufig als Vorkompilierung und "Just in Time" (JIT) oder Laufzeitkompilierung bezeichnet.
Sprachen wie C, C ++, COBOL, Fortran, Pascal (nicht alle) und Assembly sind vorkompilierte Sprachen, die direkt vom Betriebssystem ausgeführt werden können, ohne dass ein Interpreter erforderlich ist.
Sprachen wie Java, BASIC, C # und Python werden interpretiert. Sie alle verwenden den in Phase 1 erstellten Zwischencode, unterscheiden sich jedoch manchmal darin, wie sie ihn in Maschinencode umsetzen. Die einfachsten Formulare verwenden diesen Zwischencode, um Maschinencoderoutinen auszuführen, die die erwartete Arbeit ausführen. Andere kompilieren den Zwischencode bis zum Maschinencode und führen die Korrektur externer Abhängigkeiten zur Laufzeit durch. Einmal kompiliert, kann es sofort ausgeführt werden. Außerdem wird der Maschinencode in einem Cache aus zuvor kompiliertem wiederverwendbarem Maschinencode gespeichert, der später wiederverwendet werden kann, wenn die Funktion später erneut benötigt wird. Wenn eine Funktion bereits zwischengespeichert wurde, muss sie der Interpreter nicht erneut kompilieren.
Die meisten modernen Hochsprachen fallen in die Kategorie der gedolmetschten Sprachen (mit JIT). Meist sind es die älteren Sprachen wie C & C ++, die vorkompiliert werden.
quelle