OrderedDict interprétations de la
Puis-je étendre la syntaxe de python pour le dict des compréhensions pour d'autres dicts, comme le OrderedDict dans collections
module ou mes propres types qui héritent de dict
?
Juste reconsolidation du dict
nom de toute évidence ne fonctionne pas, le {key: value}
compréhension de la syntaxe encore vous donne un simple vieux dict pour des inclusions et des littéraux.
>>> from collections import OrderedDict
>>> olddict, dict = dict, OrderedDict
>>> {i: i*i for i in range(3)}.__class__
<type 'dict'>
Alors, si c'est possible comment pourrais-je aller sur le faire? C'est OK si il ne fonctionne que dans Disponible. Pour la syntaxe, je suppose que je voudrais l'essayer avec un O{k: v}
préfixe comme nous avons sur le r'various' u'string' b'objects'
.
remarque: bien sûr, on peut utiliser un générateur d'expression à la place, mais je suis plus intéressé de voir comment piratable python est en termes de grammaire.
- Par "puis-je étendre la syntaxe", entendez-vous par faire une version personnalisée de Disponible ou PyPy ou quelque chose, ou voulez-vous dire à partir de l'intérieur de la langue?
- C'est précisément là où je suis un peu largué. Peut-modules cpython être utilisé pour des choses de ce poilu, ou allons-nous obtenir dans la construction-votre-propre-python territoire ici?
- Vous pouvez étendre la {} syntaxe pour le dictionnaire des inclusions en utilisant le code suivant: stackoverflow.com/a/7880276/313113 et Vous devez ajouter un visit_DictComp() la méthode la DictDisplayTransformer classe. Si vous en avez vraiment besoin 😉
- Il suffit de déplacer à Python3.6, où les dicts sont commandés.
Vous devez vous connecter pour publier un commentaire.
Il n'y a pas de moyen direct pour modifier Python syntaxe à partir de l'intérieur de la langue. Un dictionnaire de la compréhension (ou de la plaine d'affichage) est toujours de créer un
dict
, et il n'y a rien que vous pouvez faire à ce sujet. Si vous êtes à l'aide de Disponible, c'est à l'aide de bytecode qui génèrent un dict directement, ce qui en fin de compte appeler lePyDict
fonctions de l'API et/ou les mêmes fonctions sous-jacentes utilisées par l'API. Si vous êtes à l'aide de PyPy, ceux bytecode sont plutôt mises en œuvre sur le dessus d'un RPythondict
objet qui est mis en œuvre sur le dessus d'une compilé et optimisé Pythondict
. Et ainsi de suite.Il y a un indirects façon de le faire, mais vous n'allez pas aimer ça. Si vous lisez la documentation sur le système d'importation, vous verrez que c'est l'importateur qui recherche les mises en cache le code compilé ou appelle le compilateur, et le compilateur qui appelle l'analyseur, et ainsi de suite. En Python 3.3,+, presque tout dans cette chaîne est écrite en pur Python, ou a un autre pur Python de mise en œuvre, ce qui signifie que vous pouvez fourche le code et faire votre propre chose. Qui inclut l'analyse de la source avec votre propre PyParsing code qui s'appuie ASTs, ou la compilation d'un dict compréhension de l'AST nœud dans votre propre bytecode au lieu de la valeur par défaut, ou de post-traitement le bytecode, ou...
Dans de nombreux cas, une importation crochet est suffisant; si pas, vous pouvez toujours écrire une coutume finder et chargeur.
Si vous n'êtes pas déjà à l'aide de Python 3.3 ou plus tard, je serais suggèrent fortement la migration avant de jouer avec ce genre de choses. Dans les anciennes versions, c'est plus difficile, et moins bien documenté, et vous aurez finalement être mise en 10x l'effort d'apprendre quelque chose qui sera obsolète chaque fois que vous faites migrer.
De toute façon, si cette approche semble intéressante pour vous, vous voudrez peut-être jeter un oeil à MacroPy. Vous pouvez en emprunter un peu de code à partir d'elle—et, peut-être plus important encore, apprendre comment certaines de ces caractéristiques (qui n'ont pas de bons exemples dans les docs) sont utilisés.
Ou, si vous êtes prêt à régler pour quelque chose de moins cool, vous pouvez simplement utiliser
MacroPy
à construire une "odict compréhension de la macro" et de l'utiliser. (Notez que MacroPy fonctionne actuellement uniquement en Python 2.7, pas 3.x.) Vous ne pouvez pas tout à fait obteniro{…}
, mais vous pouvez obtenir, disons,od[{…}]
, ce qui n'est pas trop mauvais. Téléchargerod.py
,realmain.py
, etmain.py
, et exécuterpython main.py
le voir fonctionner. La clé est de ce code, qui prend uneDictionaryComp
AST, la convertit en un équivalentGeneratorExpr
sur la clé-valeurTuple
s, et l'enveloppe dans unCall
àcollections.OrderedDict
:Une autre alternative est, bien sûr, de modifier l'interpréteur Python.
Je voudrais suggérer la suppression de la
O{…}
syntaxe idée pour votre premier rendez-vous, et juste normal dict interprétations de la compilation de odicts. La bonne nouvelle, c'est que vous n'avez pas vraiment besoin de changer la grammaire (ce qui est au-delà de poilue...), juste de l'un des documents suivants:PyDict
typeLa mauvaise nouvelle, alors que tous ceux-là sont beaucoup plus facile que de changer la grammaire, aucun d'eux ne peut être fait à partir d'un module d'extension. (Eh bien, vous pouvez faire le premier en fait essentiellement la même chose que vous feriez à partir de pur Python... et vous pouvez le faire en crochet .donc/.dll/.dylib de patch dans vos propres fonctions, mais c'est exactement le même travail que le piratage sur Python, plus le supplément de travail de se connecter à l'exécution.)
Si vous voulez pirater sur Disponible source, le code que vous voulez est en
Python/compile.c
,Python/ceval.c
, etObjects/dictobject.c
, et la dev guide vous dit comment trouver tout ce dont vous avez besoin. Mais vous pourriez envisager de piratage sur PyPy source au lieu de cela, puisque c'est surtout écrit dans (une sous-ensemble de) Python plutôt que de C.Comme une note de côté, votre tentative n'aurait pas travaillé, même si tout est fait à l'Python niveau de langue.
olddict, dict = dict, OrderedDict
crée une liaison nommédict
dans votre module global, qui ombres le nom dans les builtins, mais ne la remplace pas. Vous peut remplacer les choses dans les builtins (bien, Python ne garantit pas cela, mais il ya de mise en œuvre/version spécifique de choses-qui-arrive-à-travaux pour l'exécution de chaque/version que j'ai essayé...), mais ce que vous avez fait n'est pas la façon de le faire.long
etunicode
changé àint
etstr
, mais la C les types sont encorePyLong
etPyUnicode
. Presque toutes les différences sont liées à de nouvelles fonctionnalités qui n'existent pas dans le 2.x. (Si vous vous plongerez dans le piratage sur Disponible lui-même, il y a beaucoup plus de différences. Mais dans la plupart des cas—à l'exception notable de l'Unicode de stockage interne—3.4 est plus simple que de 2,7, donc il a encore un sens pour apprendre le moyen le plus facile d'abord.)ctypes
/cffi
et une extension native (et peut-être Cython, trop) pour vraiment comprendre comment les choses se présentent de différents côtés.Désolé, pas possible. Dict littéraux et dict interprétations de la carte pour le haut-dict type, dans un sens, c'est codé en dur au C niveau. Qui ne peut pas être remplacée.
Vous pouvez l'utiliser comme une alternative, cependant:
Addendum: comme de Python 3.6, tous les dictionnaires Python sont commandés. Que de 3,7, c'est même une partie de la langue spec. Si vous utilisez les versions de Python, pas besoin de OrderedDict: le dict de compréhension tout fonctionne (TM).
Légèrement la modification de la réponse de @Max Noel, vous pouvez utiliser la liste de compréhension au lieu d'un générateur pour créer un OrderedDict d'une manière ordonnée (qui n'est évidemment pas possible à l'aide de dict compréhension).
OrderedDict([(0, 2), (2, 5)])
à l'aide des valeurs arbitraires.