Упорядоченные слова

Могу ли я расширить синтаксис в python для понимания dict для других dicts, например OrderedDict в модуле collections или моих собственных типов, которые наследуют от dict ?

Очевидно, что просто переписывание имени dict не работает, синтаксис {key: value} прежнему дает вам простой старый dict для понимания и литералов.

 >>> from collections import OrderedDict >>> olddict, dict = dict, OrderedDict >>> {i: i*i for i in range(3)}.__class__ <type 'dict'> 

Итак, если возможно, как я буду это делать? Это нормально, если он работает только в CPython. Для синтаксиса, я думаю, я бы попробовал его с префиксом O{k: v} как и у r'various' u'string' b'objects' .

Примечание. Конечно, мы можем использовать выражение генератора вместо этого, но мне больше интересно узнать, как взломанный python в терминах грамматики.

3 Solutions collect form web for “Упорядоченные слова”

Нет прямого способа изменить синтаксис Python внутри языка. Понимание словаря (или простого отображения) всегда будет создавать dict , и вы ничего не можете с этим поделать. Если вы используете CPython, он использует специальные байт-коды, которые напрямую генерируют dict, что в конечном итоге вызывает функции PyDict API и / или те же базовые функции, используемые этим API. Если вы используете PyPy, эти байт-коды вместо этого реализуются поверх объекта dict который, в свою очередь, реализуется поверх компиляции и оптимизации Python dict . И так далее.

Существует косвенный способ сделать это, но вам это не понравится. Если вы прочитаете документы в системе импорта , вы увидите, что импортер выполняет поиск кэшированного скомпилированного кода или вызывает компилятор и компилятор, который вызывает парсер, и так далее. В Python 3.3+ почти все в этой цепочке либо написано на чистом Python, либо имеет альтернативную чистую реализацию Python, то есть вы можете развить код и сделать свое дело. Который включает в себя синтаксический анализ исходного кода с вашим собственным кодом PyParsing, который строит AST, или компиляция AST-узла AST в свой собственный байт-код вместо стандартного или пост-обработки байтового кода или …

Во многих случаях достаточно крючка импорта ; если нет, вы всегда можете написать пользовательский искатель и загрузчик.

Если вы еще не используете Python 3.3 или более позднюю версию, я настоятельно рекомендую выполнить миграцию, прежде чем играть с этим материалом. В более ранних версиях это сложнее и менее хорошо документировано, и в конечном итоге вы будете в 10 раз пытаться узнать что-то, что будет устаревшим, когда вы будете мигрировать.

В любом случае, если этот подход кажется вам интересным, вы можете взглянуть на MacroPy . Вы могли бы заимствовать у него некоторый код – и, что еще важнее, узнать, как используются некоторые из этих функций (которые не имеют хороших примеров в документах).

Или, если вы готовы согласиться на что-то менее крутое, вы можете просто использовать MacroPy для создания «макроса понимания выражения» и использовать его. (Обратите внимание, что MacroPy работает только в Python 2.7, а не 3.x.) Вы не можете получить o{…} , но вы можете получить, скажем, od[{…}] , что не так уж плохо. Загрузите od.py , realmain.py и main.py и запустите python main.py чтобы увидеть, как он работает. Ключом является этот код, который принимает DictionaryComp AST, преобразует его в эквивалентный GeneratorExpr для ключевых слов Tuple s и переносит его в Call to collections.OrderedDict :

 def od(tree, **kw): pair = ast.Tuple(elts=[tree.key, tree.value]) gx = ast.GeneratorExp(elt=pair, generators=tree.generators) odict = ast.Attribute(value=ast.Name(id='collections'), attr='OrderedDict') call = ast.Call(func=odict, args=[gx], keywords=[]) return call 

Другой альтернативой, конечно же, является изменение интерпретатора Python.

Я бы предложил отказаться от идеи синтаксиса O{…} для вашего первого посещения, и просто сделать обычные диктовские компиляции для компиляции. Хорошая новость заключается в том, что вам не нужно менять грамматику (которая выше волосатой …), только любой из:

  • байт-коды, которые скомпилируют dictcomps,
  • как интерпретатор запускает эти байт-коды или
  • реализация типа PyDict

Плохие новости, в то время как все это намного проще, чем изменение грамматики, ни один из них не может быть выполнен из модуля расширения. (Ну, вы можете сделать первый, выполнив в основном то же самое, что вы сделали бы с чистого Python … и вы можете сделать любой из них, подключив .so / .dll / .dylib, чтобы исправлять ваши собственные функции, но это точно такая же работа, как взлом на Python плюс дополнительная работа по подключению во время выполнения.)

Если вы хотите взломать источник CPython , Python/compile.c вам код находится в Python/compile.c , Python/ceval.c и Objects/dictobject.c , а руководство dev расскажет вам, как найти все, что вам нужно. Но вы можете захотеть вместо этого взломать исходный файл PyPy , поскольку он в основном написан в (подмножестве) Python, а не C.


В качестве побочного примечания ваша попытка не сработала бы, даже если бы все было сделано на уровне языка Python. olddict, dict = dict, OrderedDict создает привязку с именем dict в olddict, dict = dict, OrderedDict вашего модуля, которая затеняет имя во встроенных функциях, но не заменяет его. Вы можете заменить вещи во встроенных (ну, Python не гарантирует этого, но есть вещи, связанные с реализацией / версией, что-бы-случиться для каждой реализации / версии, которую я пробовал …), но вы сделали это Это способ сделать это.

Извините, не возможно. Литералы Dict и диктовские представления сопоставляются со встроенным типом dict, таким образом, что они жестко закодированы на уровне C. Это нельзя переопределить.

Вы можете использовать это как альтернативу, хотя:

 OrderedDict((i, i * i) for i in range(3)) 

Немного изменяя ответ @Max Noel, вы можете использовать представление списка вместо генератора для создания OrderedDict упорядоченным способом (что, конечно же, невозможно с использованием понимания dict).

 >>> OrderedDict([(i, i * i) for i in range(5)]) OrderedDict([(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]) 
  • Получить ключевое число из OrderedDict, где ключ является кортежем
  • Преобразование dict в OrderedDict
  • Как подклассировать OrderedDict?
  • Приказ не остался в порядке
  • Использование упорядоченного dict как предметного словаря в python
  • Python OrderDict напыления по сравнению с dict ()
  • Есть ли причины не использовать упорядоченный словарь?
  • строка для преобразования OrderedDict в python
  • Итерация над словарем python для извлечения только требуемых строк
  • Могу ли я получить JSON для загрузки в OrderedDict в Python?
  • Доступ к элементам в заказе
  •  
    Interesting Posts for Van-Lav

    Python: Разрешить методы, которые не определены специально, называются ala __getattr__

    Создание древовидной структуры в моделях django?

    Каков правильный способ сортировки операторов Python `import x` и` from x import y`?

    Вызов метода python из C / C ++ и извлечение его возвращаемого значения

    Python ez_install: UnicodeDecodeError: кодек 'ascii' не может декодировать байт 0xae в позиции 11

    не может запускать файл сценария python с помощью приглашения Windows

    Как получить больше контроля над циклами в Python?

    Назначьте сразу несколько переменных с именами динамических переменных

    Почему в Python иногда из импорта PIL изображение выходит из строя и импортируется Image?

    Удалить столбцы NULL в кадре данных Pandas?

    Строка сюжета python с базой данных datetime

    Python: Быстрые и грязные типы данных (DTO)

    Объединение кортежей с использованием sum ()

    Как создать настраиваемую панель конфигурации администратора в Django?

    Как сгенерировать события нажатия клавиш на клавиатуре через Python для управления презентацией PP?

    Python - лучший язык программирования в мире.