Модуль python-benedict
представляет собой обертку стандартного словаря Python, со множеством дополнительных встроенных методов, предназначенных для создания словаря из 'сырых данных', быстрой модификации и извлечения данных по мере необходимости, перевода данных словаря в различные форматы и т.д.
python-benedict
:KeyAttr
для получения/установки значений по ключам benedict.x.y.z
.KeyPath
для получения/установки значений по ключам benedict['x.y.z']
.KeyList
для получения/установки значений по ключам benedict['x', 'y', 'z']
.[n]
.base64
, csv
, ini
, json
, pickle
, plist
, query-string
, toml
, xls
, xml
, yaml
.python-benedict
в виртуальное окружение:# создаем виртуальное окружение, если нет $ python3 -m venv .venv --prompt VirtualEnv # активируем виртуальное окружение $ source .venv/bin/activate # обновляем `pip` (VirtualEnv):~$ python3 -m pip install -U pip # можно установить только основной модуль `python-benedict`: (VirtualEnv):~$ python3 -m pip install python-benedict # Если необходимо установить все возможности модуля (VirtualEnv):~$ python3 -m pip install python-benedict[all]
В зависимости от того с какими данными предстоит работать (в основном это операции ввода/вывода) можно выбрать зависимости модуля python-benedict
, чтобы не тащить все сразу. Обычно хватает базовой установки для работы с популярными данными, такими как base64
, csv
, ini
, json
, pickle
...
Ниже представлена иерархия возможных целей установки, доступных при запуске pip install python-benedict[...]
:
- python-benedict[all] - python-benedict[io] - python-benedict[toml] - python-benedict[xls] - python-benedict[xml] - python-benedict[yaml] - python-benedict[parse] - python-benedict[s3]
benedict
.Модуль python-benedict
является подклассом dict
, поэтому его можно использовать как обычный словарь. Можно просто преобразовать обычный словарь Python в словарь benedict
.
from benedict import benedict # новый пустой экземпляр d = benedict() # или из существующего словаря Python d = benedict(existing_dict) # или создаем из источника данных # (путь к файлу, URL-адрес или строка данных) # в поддерживаемом формате: # Base64, CSV, JSON, TOML, XML, YAML, query-string d = benedict('https://localhost:8000/data.json', format='json') # можно использовать в представлении Django params = benedict(request.GET.items()) page = params.get_int('page', 1)
benedict
.К обычным методам доступа к значению словаря и добавления/изменения значения ключа словаря Python добавляются следующие...
KeyAttr
при работе со словарем benedict
.Можно получить/установить элементы, используя ключи в качестве атрибутов (точечная нотация).
>>> from benedict import benedict >>> d = benedict() >>> d.profile.firstname = 'Fabio' >>> d.profile.lastname = 'Caccamo' >>> d # {'profile':{ 'firstname':'Fabio', 'lastname':'Caccamo' } }
Предупреждение даже если эта функциональность очень полезна, у нее есть некоторые очевидные ограничения:
KeyAttr
работает только для строковых ключей;- ключи не могут начинаться с подчеркивания
_
- имена ключей не должны конфликтовать с именами поддерживаемых методов.
keyattr
:Можно отключить функцию keyattr
, передав keyattr_enabled=False
в конструкторе.
>>> from benedict import benedict >>> d = benedict(existing_dict, keyattr_enabled = False)
Также можно отключить функцию keyattr
, используя свойство:
>>> d.keyattr_enabled = False
KeyList
при работе со словарем benedict
.Везде, где используется ключ, также можно использовать список или кортеж ключей.
>>> from benedict import benedict >>> d = benedict() # установить значения по списку ключей >>> d['profile', 'firstname'] = 'Fabio' >>> d['profile', 'lastname'] = 'Caccamo' >>> d # { 'profile':{ 'firstname':'Fabio', 'lastname':'Caccamo' } } >>> d['profile'] # { 'firstname':'Fabio', 'lastname':'Caccamo' } # проверка существования пути к ключу >>> ['profile', 'lastname'] in d # True # удалить значение по списку ключей >>> del d['profile', 'lastname'] >>> d['profile'] # { 'firstname':'Fabio' }
KeyPath
при работе со словарем benedict
.Разделителем пути по умолчанию является точка .
>>> from benedict import benedict >>> d = benedict() # установить значения по пути >>> d['profile.firstname'] = 'Fabio' >>> d['profile.lastname'] = 'Caccamo' >>> d # { 'profile':{ 'firstname':'Fabio', 'lastname':'Caccamo' } } >>> d['profile'] # { 'firstname':'Fabio', 'lastname':'Caccamo' } # проверка существования пути к ключу >>> 'profile.lastname' in d # True # удаление значения по пути >>> del d['profile.lastname']
Точка .
в качестве разделителя пути к ключам конечно удобно, но это обстоятельство накладывает некоторые ограничения. Например, если обычный словарь Python имеет ключ, в названии которого содержится точка, например 'awesome.com'
, то при преобразовании его в benedict
будет появляться ошибка.
data = { 'awesome.com': 'https://awesome.com', 'skills': { 'programming': { 'Python': '5 stars', 'JavaScript': '4 stars', } } } >>> data = benedict(data) # Traceback (most recent call last): # ... # ValueError: Key should not contain keypath separator '.', found: 'awesome.com'.
Чтобы обойти это ограничение, benedict
предоставляет параметр keypath_separator
для указания другого разделителя.
Можно настроить разделитель 'путей к ключу', передав аргумент keypath_separator
в конструкторе.
data = benedict(data, keypath_separator='/') # теперь можно получить доступ к фактическому ключу print(data['awesome.com']) # https://awesome.com # а так же обратиться, используя разделитель пути '/' print(data['skills/programming/Python']) # 5 stars
Также можно изменить keypath_separator
в любое время, используя свойство:
data.keypath_separator = '|'
Если какой-либо существующий ключ словаря содержит значение keypath_separator
, то будет возбуждено исключение. Например, словарь содержит ключ 'awesome.com'
# попробуем изменить разделитель пути снова на точку data.keypath_separator = '.' # Traceback (most recent call last): # ... # ValueError: Key should not contain keypath separator '.', found: 'awesome.com'.
keypath
.Можно отключить функцию keypath
, передав в конструкторе keypath_separator=None
.
d = benedict(existing_dict, keypath_separator=None)
Также можно отключить функцию keypath
, используя свойство:
d.keypath_separator = None
'Пути к ключам' могут включать индексы (также отрицательные) с использованием [n]
для очень быстрого выполнения любой операции:
Например, получим координаты последнего местоположения первого результата:
loc = d['results[0].locations[-1].coordinates'] lat = loc.get_decimal('latitude') lng = loc.get_decimal('longitude')
benedict
.from benedict import benedict data = { 'name': 'Josh', 'occupation': 'Data scientist', 'skills': { 'programming': { 'Python': '5 stars', 'JavaScript': '4 stars', 'Java': '3 stars' }, 'frameworks': ['Django', 'React', 'Spring'] } } # инициализируем словарь data = benedict(data) # проверка существования пути if 'skills.programming.Java' in data: print(data['skills.programming.Java']) # '3 stars' # или эквивалентно print(data['skills', 'programming', 'Java']) # '3 stars' # путь к несуществующему ключу print('skills.softskills.managing' in data) # False # можно также использовать `.get(...)` print(data.get('skills.softskills.managing')) # None # можно добавлять пути data['skills.softskills.managing'] = '5 stars' print(data['skills', 'softskills', 'managing']) # '5 stars' # вывод словаря в читаемом виде print(data.dump()) # { # 'name': 'Josh', # 'occupation': 'Data scientist', # 'skills': { # 'frameworks': [ # 'Django', # 'React', # 'Spring' # ], # 'programming': { # 'Java': '3 stars', # 'JavaScript': '4 stars', # 'Python': '5 stars' # }, # 'softskills': { # 'managing': '5 stars' # } # } # }