👩💻
DSL в Python через __call__ и __getitem__
— красиво, читаемо, PythonicХочешь, чтобы твой код выглядел как язык сам по себе?
Python позволяет строить
мини-языки внутри кода — без библиотек, просто на магии dunder-методов.
✔️
Начнём с __call__
Он делает объект вызываемым, как функцию:
class Hello:
def __call__(self, name):
return f"Привет, {name}!"
h = Hello()
print(h("Мир")) # Привет, Мир!
Полезно, когда хочется сделать объекты лаконичными. Можно даже прокидывать параметры как в обычной функции.
✔️
Теперь __getitem__
Позволяет обращаться к объекту через квадратные скобки:
class SecretBox:
def __getitem__(self, key):
return f"🔒 Внутри: {key}"
box = SecretBox()
print(box["password"]) # 🔒 Внутри: password
Ты можешь использовать это для красивого синтаксиса без точек и скобок.
🤝
Комбинируем в DSLclass SQL:
def __call__(self, table):
return f"SELECT * FROM {table}"
def __getitem__(self, field):
return f'"{field}"'
q = SQL()
print(q("users")) # SELECT * FROM users
print(q["email"]) # "email"
Теперь у нас объект, который и вызывает таблицу, и красиво оформляет поля.
🧪
Более мощный пример: API-доступclass API:
def __init__(self, base):
self.base = base
def __getitem__(self, endpoint):
return f"{self.base}/{endpoint}"
def __call__(self, endpoint, **params):
query = "&".join(f"{k}={v}" for k, v in params.items())
return f"{self.base}/{endpoint}?{query}"
api = API("https://api.server")
print(api["users"]) #
https://api.server/usersprint(api("users", id=5, active=True)) #
https://api.server/users?id=5&active=TrueТакой подход часто используют в клиентах к REST API, чтобы код выглядел как естественный DSL.
🧰
А можно вообще без классов?class K:
def __getitem__(self, key):
return lambda d: d.get(key)
k = K()
data = {"name": "Neo", "role": "Hacker"}
print(k["name"](data)) # Neo
print(k["role"](data)) # Hacker
Так строятся мини-функции доступа к полям. Особенно круто в map/filter.
🗣️
Запомни: __call__ и __getitem__ — это способ превратить скучные объекты в выразительный синтаксис. Так строятся мини-языки прямо в Python: понятные, компактные и без лишнего шума.