In Vorheriger Beitrag habe ich ein Tool zum gleichzeitigen Ausführen und Archivieren von Quellcode vorgestellt. Die Einführung dieser Zeit ist ein Tool, das Hy nativ kompiliert, um ausführbare Dateien und gemeinsam genutzte Bibliotheken zu erstellen. Sie können es auch in die Python- oder C-Sprache konvertieren. Es ist in PyPI unter dem Namen HyCC registriert. Es besteht jedoch weiterhin die Möglichkeit ** unerwarteter Fehler **. Verwenden Sie diese daher bitte unter ** Eigenverantwortung **. Übrigens ** sind alle in Hy ** implementiert.
Bitte installieren Sie von pip
.
** Der Vorgang in der Windows-Umgebung wurde jedoch nicht bestätigt. ** ** **
$ pip install hycc
~~ Wenn die neueste Version von PyPI Hy (v0.12.1) ist, kann ein Code aufgrund eines Fehlers in Hy einen Fehler verursachen. Installieren Sie daher bitte die neueste Version von Github. ~~ ** 01.07.2017 Nachtrag: Diese Arbeit ist aufgrund der Aktualisierung von Hy und HyCC nicht mehr erforderlich. **
Nachdem die Vorbereitung abgeschlossen ist, nehmen wir den folgenden Code als Beispiel.
hello.hy
(defn hello []
(print "hello!"))
(defmain [&rest args]
(hello))
$ hycc hello.hy
Dadurch wird eine ausführbare Binärdatei mit dem Namen "Hallo" im aktuellen Verzeichnis erstellt.
$ ./hello
hello!
Erstellen Sie mit der Option "--shared".
$ hycc hello.hy --shared
Dadurch wird ein freigegebenes Objekt mit dem Namen "hello.so" im aktuellen Verzeichnis erstellt. Python kann gemeinsam genutzte Objekte als Module importieren, aber Hy ist natürlich dasselbe. Daher kann dieses "Hallo" wie folgt verwendet werden.
Hy zu hallo.so importieren
(import hello)
(hello.hello)
; >hello!
Hallo von Python.so importieren
import hello
hello.hello()
# >hello!
Nativ kompilierte Module und ausführbare Dateien sind ** etwa 2-8 mal schneller **. Ich denke, es ist nützlicher als die Verwendung von "hyc" zum Byte-Kompilieren in eine ".pyc" -Datei. Und natürlich ** schneller als Python **. Intern wird Cython verwendet, aber das Bild der Geschwindigkeit ist wie folgt.
** C <Cython (mit Typspezifikation) << Cython (ohne Typspezifikation) <HyCC <Python <Hy **
Es ist im Allgemeinen ** aufwärtskompatibel mit hyc
**, aber es gibt eine Einschränkung **. Da es sich um den internen Mechanismus handelt, werde ich ihn erläutern und den Mechanismus im Folgenden erläutern.
Grob gesagt wird Hy-Code in Python konvertiert, über Cython in C konvertiert und kompiliert. Wie in Letzter Beitrag erwähnt, wurde der Python-Code jedoch mit dem im Lieferumfang von Hy enthaltenen "hy2py" generiert. ** Funktioniert nicht so wie es ist **. Daher ist es nicht möglich, nur "hy2py" und "cythonize" zu verwenden.
Erstens ** Warum funktioniert der Code, den hy2py
ausspuckt, nicht **? Weil Python einen ungültigen Bezeichner verwendet. Die ungültigen Bezeichner in Python sind:
Nehmen Sie den folgenden Code als Beispiel.
sample.hy
(reduce + [1 2 3])
; > 6
Wenn Sie dies mit "hy2py" konvertieren, erhalten Sie Folgendes.
Code, den hy2py spuckt
from hy.core.language import reduce
from hy.core.shadow import +
# +Ist eine ungültige Kennung
reduce(+, [1, 2, 3])
Hier ist +
die obige 2. Weil es entspricht, ist es nutzlos. Das einfache Ersetzen durch einen anderen gültigen Namen wie "Hinzufügen" funktioniert nicht.
Von dem Code, den hy2py spuckt+Durch Hinzufügen ersetzen
from hy.core.language import reduce
from hy.core.shadow import add
# ImportError
reduce(add, [1, 2, 3])
Offensichtlich ist für das Modul "hy.core.shadow" nicht der Name "add" definiert, daher ist es "ImportError". HyCC generiert zunächst den folgenden Python-Code aus der Hy-Quelle, um dieses Problem zu lösen.
HyCC Weg
import hy.core.language as _
reduce = _.getattr("reduce")
import hy.core.shadow as _
+ = _.getattr("+")
reduce(+, [1, 2, 3])
Dieser Code entspricht dem Code, den hy2py
ausspuckt, aber Sie können +
durch einen beliebigen Namen ersetzen. HyCC vermeidet Fehler, indem der Zugriff auf AST-Ebene und der Zugriff auf Quellcode-Ebene ordnungsgemäß kombiniert werden. Ebenso wird der Mitgliederzugriff des Objekts mit "getattr" und "setattr" neu geschrieben.
Informationen zu den oben genannten Vorsichtsmaßnahmen bei der Verwendung von HyCC. Wie bisher erläutert, ersetzt HyCC ungültige Kennungen durch gültige mit einigem Einfallsreichtum. Zu diesem Zeitpunkt tritt nur eine Nebenwirkung oder ein Problem auf.
HyCC Bösewicht
(def hoge/fuga 0)
(print (get (globals) "hoge/fuga"))
; > 0
Der obige Code wird von HyCC in den folgenden Python-Code konvertiert.
Von HyCC generierter Code
from __future__ import print_function
import hy
hogex2Ffuga = 0L
print(globals()[u'hoge/fuga'])
Sie können das Hinzufügen einiger Importe ignorieren. Im ursprünglichen Hy-Code war "hoge / fuga" ein ungültiger Name in Python. Daher wird es im von HyCC generierten Code durch "hogex2Ffuga" ersetzt.
Das Ausführen dieses Codes führt zu folgendem Fehler.
File "test.py", line 4, in <module>
print(globals()[u'hoge/fuga'])
KeyError: u'hoge/fuga'
Hast du verstanden? Der negative Effekt des Ersetzens eines ungültigen Bezeichners durch einen gültigen besteht darin, dass die Module "Globals", "Locals" und "Inspect" in einigen Fällen möglicherweise nicht ordnungsgemäß funktionieren.
Wir erwägen einige Gegenmaßnahmen für dieses Problem, aber ** Hy selbst hat bereits ein ähnliches Problem **. In Hy wird "hoge!" In der Phase der Syntaxanalyse durch "hoge_bang" und "hoge" ersetzt. "Wird durch" is_hoge "ersetzt. Daher funktioniert der folgende Code nicht ordnungsgemäß.
Hy und Bösewicht
(def hoge! 0)
(print (get (globals) "hoge!"))
; > KeyError!
Daher kann die Verwendung von "Globals" usw. als ** Vorsichtsmaßnahmen bei der Verwendung von HyCC und nicht als Vorsichtsmaßnahmen bei der Verwendung von HyCC ** bezeichnet werden.
*** 2017/06/04 Nachtrag *** ** Unterstützt durch Update! ** Insbesondere wird ein Schlüsselfehler vermieden, indem "Globale" und "Einheimische" in eine Mystery-Klasse wie "dict" eingeschlossen werden. Wie üblich funktioniert das "inspect" -Modul nicht richtig, aber ** Cython selbst unterstützt "inspect" ** nicht, daher kann ich nichts dagegen tun. Weitere Informationen finden Sie unter This Commit.
HyCC hat auch eine Funktion zum Konvertieren von Hy nach Python wie "hy2py".
$ hycc hello.hy --python
Dies gibt "hello.py" in das aktuelle Verzeichnis aus. Wenn Sie die obigen Hinweise beachten, funktioniert es im Gegensatz zu dem von ** hy2py
** ausgegebenen Code ordnungsgemäß. Überraschenderweise ist diese Funktion möglicherweise stärker gefragt. Ebenso kann es mit der Option "--clang" in die Sprache C konvertiert werden, es ist jedoch schwierig, ob es verwendet werden kann.
Wie ich in Github-Ausgaben geschrieben habe, handelt es sich um eine Python-Spezifikation? Wenn Sie ein Submodul mit gettatr
für ein Modulobjekt erhalten Es scheint "AttributeError" zu sein, wenn das Submodul eine gemeinsam genutzte Bibliothek enthält. Ich denke darüber nach, wie ich damit umgehen soll.
Einführung von Tool zum nativen Kompilieren von Hy. Die gesamte Entwicklung erfolgt auf github. Sie können sich also gerne an Pururiku wenden. Sie können Pulls werfen) oder Probleme. Kommentare hier sind natürlich auch willkommen. Hy ist immer noch eine sich entwickelnde verdammte Nebensprache, aber ich hoffe, dass sie mit zunehmender Anzahl von Benutzern und aktiveren Diskussionen komplexer wird. Vielen Dank, dass Sie so weit gelesen haben.
Recommended Posts