TGTGInsighttelegram intelligenceLIVE / telegram public index
← Python Заметки
Python Заметки avatar

TGINSIGHT POST

Post #211

@pythonotes

Python Заметки

Прегледи2,120Број на прегледи
Објавено5 фев.05.02.2021 г., 09:00
Содржина

Содржина на објавата

Можно ли создать инстанс класса используя квадратные скобки вместо круглых? 🙄 Казалось бы, чего сложного, делаем метод __getitem__ как classmethod и готово class MyClass: def __init__(self, value): self.value = value @classmethod def __getitem__(cls, item): return cls(item) Но нет, такой финт не сработает. >>> inst = MyClass[5] TypeError: 'type' object is not subscriptable Тип данного класса не поддерживает такой интерфейс. Чтобы поддерживал, нужно изменять его метакласс. Ниже представлен простой пример добавления метода __getitem__ в тип класса. class PresetsType(type): presets = { 'red': '#ff0000', 'green': '#00ff00', 'blue': '#0000ff'} def __getitem__(self, item): instance = self(self.presets[item]) return instance Получилось что-то вроде пресетов, доступных при создании инстанса через квадратные скобки. Теперь используем новый тип как метакласс нашего класса. class Color(metaclass=PresetsType): def __init__(self, value): self.value = value def __repr__(self): return f'<Color "{self.value}">' Можно тестить! # создаём инстанс обычным способом >>> c1 = Color('#ffb905') >>> print(c1) <Color "#ffb905"> # теперь через квадратные скобки >>> c2 = Color['red'] >>> print(c2) <Color "#ff0000"> На сколько пример актуальный в реальной работе, решать вам. Но он точно неочевидный😜 Как еще можно это использовать? 🔸 как-либо модифицировать класс и возвращать тоже класс вместо готового инстанса 🔸 возвращать сразу список инстансов. Например, в случаях когда используется срез 🔸 возвращать разные версии классов по имени под разные ситуации, например унаследованные классы с доп. интерфейсом Начиная с версии 3.7 у появилась возможность сделать тоже самое без мета класса! В PEP 560 добавили magic-метод __class_getitem__(cls). Теперь наш класс будет выглядеть так: class Color: presets = { 'red': '#ff0000', 'green': '#00ff00', 'blue': '#0000ff'} def __init__(self, value): self.value = value def __repr__(self): return f'<Color "{self.value}">' def __class_getitem__(cls, item): return cls(cls.presets[item]) #tricks