OrderedDict-Übersichten
Kann ich verlängern syntax in python dict Verstehens für die anderen dicts, wie die OrderedDict in collections
- Modul oder eigene Typen, die die Erben von dict
?
Nur neubindung der dict
Namen offensichtlich nicht funktioniert, die {key: value}
Verständnis der syntax, noch gibt Sie eine einfache alte dict-für Verstehens-und Literale.
>>> from collections import OrderedDict
>>> olddict, dict = dict, OrderedDict
>>> {i: i*i for i in range(3)}.__class__
<type 'dict'>
So, wenn es möglich ist, wie würde ich tun? Es ist OK, wenn es funktioniert nur in CPython. Für die syntax, die ich denke, ich würde versuchen es mit einem O{k: v}
Präfix wie haben wir auf der r'various' u'string' b'objects'
.
Hinweis: natürlich können wir einen generator-Ausdruck anstelle, aber ich bin mehr daran interessiert zu sehen, wie hackable python ist in Bezug auf die Grammatik.
InformationsquelleAutor der Frage wim | 2014-01-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es keine direkte Möglichkeit, dies zu ändern-Python-syntax innerhalb der Sprache. Eine dictionary comprehension (oder nur-Anzeige) ist immer ein
dict
und es gibt nichts, was Sie dagegen machen können. Wenn Sie mit CPython, es ist mit speziellen Bytecode generieren, dass ein dict-direkt, die letztlich rufen Sie diePyDict
API-Funktionen und/oder der gleichen zugrunde liegenden Funktionen verwendet, die API. Wenn Sie mit PyPy, diejenigen, die bytecodes sind stattdessen implementiert auf einem RPythondict
- Objekt, das wiederum umgesetzt auf der Spitze eines kompiliert und optimiert Pythondict
. Und so weiter.Es ist ein indirekte Weg, es zu tun, aber du nicht gehst, es zu mögen. Wenn Sie die Dokumentation Lesen, auf das import-systemwerden Sie sehen, dass es der Importeur, die Suche nach Cache-kompilierten code oder ruft die compiler und der compiler ruft den parser, und so weiter. In Python 3.3+, fast alles, was in dieser Kette entweder ist geschrieben in reinem Python, oder hat eine Alternative Reine Python-Implementierung, das heißt, Sie können die Gabel den code und Ihr eigenes Ding machen. Das umfasst die Analyse der Quelle mit eigenen PyParsing-code, der baut ASTs, zusammenstellen oder ein dict-comprehension AST-Knoten in Ihrem eigenen bytecode statt der Standard-oder post-processing-bytecode, oder...
In vielen Fällen eine import-hook ausreichend ist; wenn nicht, können Sie immer schreiben Sie einen benutzerdefinierten finder und loader.
Wenn Sie nicht bereits mit Python 3.3 oder später, würde ich empfehlen dringend die Migration vor dem spielen mit diesem Zeug. In älteren Versionen, ist es schwieriger und weniger gut dokumentiert, und schließlich Sie werden putting in der 10-fachen Aufwand, um etwas zu lernen, die obsolet werden, wenn Sie migrieren.
Sowieso, wenn dieser Ansatz klingt für Sie interessant, möchten Sie vielleicht werfen Sie einen Blick auf MacroPy. Sie leihen könnte einige coding—und, was vielleicht noch wichtiger ist, lernen, wie man einige dieser features (, die haben keine guten Beispiele in der Dokumentation) verwendet werden.
Oder, wenn Sie bereit sind, sich für etwas weniger kühl, können Sie einfach
MacroPy
zu bauen "odict Verständnis makro" und verwenden. (Beachten Sie, dass MacroPy funktioniert bisher nur in Python 2.7, nicht 3.x.) Sie kann nicht Recht bekommeno{…}
ist, aber Sie können, sagen,od[{…}]
das ist nicht zu schlecht. Downloadod.py
realmain.py
undmain.py
und führen Siepython main.py
zu sehen, dass es funktioniert. Der Schlüssel ist, diesen code, der eineDictionaryComp
AST, wandelt es sich zu einem gleichwertigenGeneratorExpr
auf Schlüssel-Wert -Tuple
s, und wickelt es in einCall
zucollections.OrderedDict
:Eine andere alternative ist natürlich, zu ändern, den Python-interpreter.
Ich würde vorschlagen, fallen die
O{…}
syntax Idee für Ihren ersten gehen, und nur eine normale dict Verstehens zu kompilieren odicts. Die gute Nachricht ist, Sie nicht wirklich brauchen, um zu ändern, die Grammatik (die ist über Behaarte...), nur eine von:PyDict
TypDen schlechten Nachrichten, während alle diese sind sehr viel leichter als eine änderung der Grammatik, keiner von Ihnen getan werden kann, von einem Erweiterungsmodul. (Gut, die Sie tun können, das erste durch tun im Grunde die gleiche Sache, die Sie tun würde, von der reinen Python... und Sie können jede von Ihnen durch Einhaken der .so/.dll/.dylib-patch in Ihren eigenen Funktionen, aber das ist die genau die gleiche Arbeit wie hacken auf Python plus die zusätzliche Arbeit der Haken bei der runtime.)
Wenn Sie wollen hack auf CPython Quelleden code, den Sie wollen, ist in
Python/compile.c
Python/ceval.c
undObjects/dictobject.c
und die dev guide erzählt, wie Sie finden alles, was Sie brauchen. Aber möchten Sie vielleicht zu prüfen, hacken PyPy Quelle statt, da es meistens geschrieben in (einer Teilmenge von) Python eher als C.Als eine Randnotiz, der Versuch hätte nicht funktioniert, selbst wenn alles wurden an der Python-Sprache-Ebene.
olddict, dict = dict, OrderedDict
wird eine Bindung namensdict
Sie in Ihrem Modul die globals, die Schatten den Namen in der gelieferten, aber nicht ersetzen. Sie kann ersetzen Sie Dinge, die in der gelieferten (auch Python keine Garantie, aber es gibt-Implementierung/-version-spezifische Dinge-das-geschehen-zu-arbeiten für jede Anwendung/version habe ich versucht...), aber was du getan hast ist nicht der Weg, es zu tun.InformationsquelleAutor der Antwort abarnert
Sorry, nicht möglich. Dict-Literale und dict Verstehens Karte, um das built-in-dict-Typ, in einer Weise, die hartcodiert auf C-Ebene. Das kann nicht überschrieben werden.
Können Sie diese verwenden, als eine alternative, obwohl:
InformationsquelleAutor der Antwort Max Noel
Leicht zu modifizieren: die Antwort von @Max Noel, die Sie verwenden können, Liste, Verständnis, anstatt einen generator zum erstellen eines OrderedDict in einer geordneten Art und Weise (was natürlich nicht möglich ist, mithilfe von dict-comprehension).
InformationsquelleAutor der Antwort Alexander