TGViewer
Python Заметки Python Заметки @pythonotes · 2.2K subscribers
Post #211 2.12K
Можно ли создать инстанс класса используя квадратные скобки вместо круглых? 🙄
Казалось бы, чего сложного, делаем метод __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
More from @pythonotes
  1. Sep 21, 2026­ WebAssembly это мощная технология позволяющая загружать практически любое приложение в б…
  2. Aug 17, 2026Не так давно столкнулся с API который в ответе с ошибкой присылал только статус-код. Без п…
  3. Jul 20, 2026У меня основная ОС это Linux. Но нередко требуется делать сборку клиента под Windows. Соби…
  4. Jul 13, 2026В прошлый раз был пример с понижением привелегий процесса. Проблема в том, что обратно под…
  5. Jul 6, 2026Модуль pwd может использоваться для считывания информации о пользователях из базы данных п…
  6. Jun 22, 2026Недавно я реализовал Multi Tenancy систему на FastAPI + SQLAlchemy и пересобрал её в небол…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →