Каковы лучшие практики Python для ключевых словарных констант? - PullRequest
15 голосов
/ 22 мая 2011

При использовании словарных (dict) ключей в Python существует несколько общих подходов:

  1. some_dict['key_name'] # string constants everywhere

  2. some_dict[KeyConstants.key_name] # where class KeyConstants: key_name: 'key_name'

  3. some_dict[KEY_NAME] # with from some_module import KEY_NAME # a module level constant

    1. 'key_name' имеет тот недостаток, что вы повторяете константы по всему коду.Это не СУХОЙ.Хуже того, если вы когда-нибудь захотите опубликовать свой API (в самом широком смысле), у вас будут потребители вашего API, повторяющие эти константы повсюду, и если вы когда-нибудь захотите изменить «key_name» на «better_key_name», это будет серьезное изменение.

    2. Это типизированный язык, СУХОЙ, с константами, объединенными в одном месте.Его единственные недостатки в том, что он уродлив, немного менее читабелен и более многословен.Pythonic принципы в первую очередь запрещают это.Это позволяет вам легко изменять константу, представляющую ключ, так как все кодируют переменную KeyConstants.key_name.Он также хорошо работает с IDE для рефакторинга.

    3. Константы уровня модуля рекомендуются в руководстве по стилю PEP 8.ALL_CAPS_ARE_LOUD и сложнее набрать.В этом есть некоторые преимущества обоих вариантов 1 и 2.

Каковы некоторые другие лучшие практики для ключевых слов в качестве констант?Какой из перечисленных подходов предпочтительнее и когда?

Ответы [ 2 ]

4 голосов
/ 22 мая 2011
  1. d [ 'key_name']
  2. д [Keys.key_name] * * +1004
  3. д [KEY_NAME]

Я на самом деле не считаю № 3 требованием импорта на уровне модуля; они просто могут быть в пространстве имен модуля, например Вы могли бы сделать что-то вроде Как программно установить глобальную (модульную) переменную?

Преимущество # 2 перед # 1 в том, что опечатки и устаревшие значения приведут к ошибке атрибута "этот ключ не существует!" а не ошибка индекса "не удалось найти!" - что всегда лучше. # 2> # 1. Это также не более многословно, потому что вы просто устанавливаете K=Keys (или что-то еще), если вы много печатаете, поэтому у вас есть d[K.key_name], всего на два символа больше (). Например, в зависимости от того, как я себя чувствую, я могу сделать следующее:

import subprocess as proc
proc.Popen(..., stdout=proc.PIPE)

или

import subprocess as proc
PIPE = proc.PIPE
proc.Popen(..., stdout=PIPE)

или

from subprocess import *
Popen(..., stdout=PIPE)

Что касается # 3, ALL_CAPS_ARE_LOUD по причине; сбивает с толку различие между d[someVariable] (которое может содержать любое ключевое слово) и d[magicKeyword] - тогда как d[MAGIC_KEYWORD] однозначно говорит о том, что это константа, а не некоторая переменная, которая может содержать константу, например, for someVariable in magicKeywords. # 3 в основном эквивалентно # 2, например re.DOTALL (re эквивалентен KeyConstants, без необходимости запоминать имя KeyConstants контейнеров, потому что является модулем). Таким образом, # 3 превосходит # 2, если вы не находитесь в странной ситуации, когда у вас есть разные типы пространств клавиш.

DRY / OAOO очень и очень важен, но в конечном итоге не имеет отношения ни к одному из них, потому что вам всегда нужно повторять имя переменной, чтобы ссылаться на нее; лучшее, что вы можете сделать, это создать псевдоним.

Вы могли бы также рассмотреть # 4, который должен снабдить ваш словарь атрибутами, например d.key_name - это уместно, только если это какой-то подписываемый объект.

Но процитирую комментарий Йохена Ритцеля: «Использование постоянных ключей должно быть очень редким случаем» (используйте атрибуты объекта или, как он предлагает, возможно, именованный кортеж, хотя я всегда нашел их громоздкими)

2 голосов
/ 01 мая 2015

Это старый вопрос, но вы проверили Букет ?Это словарь, который поддерживает доступ в стиле атрибутов, как JavaScript.

>>> from bunch import bunchify
>>> from bunch import unbunchify
>>> import datetime as dt

>>> my_dict = {'a': 'a', 'b': [{'c': 'c', 'n': 1}, {'c': 'k', 'n': 2}], 'dt': dt.datetime.utcnow()}

>>> my_dict_obj = bunchify(my_dict) 
>>> my_dict_obj.b[0].c
'c'
>>>  'a' in my_dict_obj
True
>>>  'x' in my_dict_obj
False
>>> my_dict = unbunchify(my_dict_obj)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...