
Привет. Хочу познакомить вас библиотекой Munch, которая является форком более старой библиотеки Bunch. Рассмотрим суть проблемы, которую она решает. Задать атрибуты объекта, не описывая их по одному в конструкторе. Легче понять на примере:
>>> f = object() >>> f.x = 10 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'object' object has no attribute 'x'
Видно, что object нам не поможет. Но в Python 3 можно сделать пустой класс, это не вызовет ошибки:
class Bunch: ... foo = Bunch() foo.x = 10 foo.y = 20
И в принципе этого может быть достаточно. Но иногда хочется больше. В моей практике возникла задача, когда нужно было имитировать классы из сторонней библиотеки. Использовать сами эти классы было громоздко и неудобно, потому что там было много лишнего кода, и нужно было придумать решение, как от него избавиться, чтобы избежать ошибок и побочных эффектов. Пришла на помощь библиотека с которая к слову имеет кучу мелких удобных возможностей.
Установка:
pip install munch
Объект Munch – это наследник словаря dict, с ним можно работать как со словарем, но можно также произвольно работать с его атрибутами:
from munch import * # пустой b = Munch() # задаем атрибуты b.hello = 'world' print(b.hello) # world b['hello'] += "!" print(b.hello) # world! print(b.hello is b['hello']) # True # атрибут может быть тоже Munch b.bar = Munch() b.bar.baz = 100 print(b.bar.baz) # 100
Т.е. мы может обращаться к данным как через точку (как атрибут), так и через квадратные скобки (как с обычным словарем) – это будут одни и те же данные, при условии равных имен.
Очень удобная фишка – создание Munch через конструктор, просто перечисляем ключевые слова, и они станут атрибутами:
# задать через конструктор c = Munch(x=10, y=20, z=30) print(c.x, c.y, c.z) # 10 20 30
С Munch можно работать, как с обычным dict, например:
c = Munch(x=10, y=20, z=30) print(list(c.keys())) # список атрибутов c.update({ 'w': 10, 'name': 'ganesh' }) print(c) # Munch({'x': 10, 'y': 20, 'z': 30, 'w': 10, 'name': 'ganesh'}) print([(k, v) for k, v in c.items()]) # [('x', 10), ('y', 20), ('z', 30), ('w', 10), ('name', 'ganesh')]
Удобно сеарилизовтать такие объекты:
# JSON b = Munch(foo=Munch(lol=True), hello=42, ponies='are pretty!') import json print(json.dumps(b)) # {"foo": {"lol": true}, "hello": 42, "ponies": "are pretty!"} # YAML - если есть. import yaml print(yaml.dump(b)) # или print(yaml.safe_dump(b))
Замечание
В библиотеку collections Python 3 уже включен объект UserDict со схожей функциональностью:
from collections import UserDict a = UserDict() a.p = 10
Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈