Python DSL: адаптированные решения для специализированных доменов
Когда мы пишем программу, мы обнаруживаем, что решаемые проблемы относятся к конкретным областям, также называемым доменами, например:
- Банковская система должна описывать транзакции, процентные ставки.
- Веб-приложение должно определять маршруты, шаблоны и ответы.
Используя язык общего назначения (GPL) вроде Python или Java, мы можем решать эти проблемы, но код становится слишком детализированным и повторяющимся. Поэтому мы будем использовать DSL (Domain Specific Language — предметно-ориентированный язык).
DSL — Предметно-ориентированный язык
Предметно-ориентированный язык — это язык программирования или спецификации, посвященный конкретному домену. Он отличается от языка общего назначения (GPL вроде Python, C++ или Java). Они бывают двух типов:
- Внешний DSL — это полностью новый язык со своим синтаксисом и компилятором
- Внутренний DSL (Embedded DSL) — DSL, построенный внутри хост-языка, используя его синтаксис и конструкции.
Внешний DSL
Для работы с базами данных мы используем SQL, вместо написания циклов для ручного сканирования данных мы просто пишем:
SELECT name FROM users WHERE age > 10;
Для проектирования веб-страниц мы используем HTML, вместо ручного управления строками текста и позициями мы просто объявляем:
<h1>Welcome To Tutorialspoint</h1>
Внутренний DSL
В Python предметно-ориентированный язык строится на вершине синтаксиса Python. Фреймворки вроде Flask или Pandas — примеры DSL-подобных библиотек, помогающих выражать проблемы четко.
@app.route('/home')
def home():
return "Hello...!"
Зачем DSL в Python
Python — лучший выбор для DSL, потому что:
- Его синтаксис прост и выразителен.
- Он позволяет использовать функции и классы как строительные блоки.
Например, тестовые фреймворки вроде pytest или веб-фреймворки вроде Flask — это DSL-подобные. Вместо написания низкоуровневой логики они позволяют писать выразительные команды.
Погрузимся в пример, чтобы узнать больше о предметно-ориентированном языке.
Пример 1
Посмотрим на следующий пример, где мы абстрагируем язык математики в именованные функции.
def add(x, y):
return x + y
def multiply(x, y):
return x * y
print(add(multiply(1, 3), multiply(2, 4)))
Вывод вышеуказанной программы:
11
Пример 2
Рассмотрим следующий пример, где мы используем DSL в конфигурационных файлах.
class demo:
def __init__(self):
self.settings = {}
def set(self, key, value):
self.settings[key] = value
return self
def get(self, key):
return self.settings.get(key)
result = demo()
result.set("host", "Welcome").set("port", 1231)
print(result.get("host"))
Вывод вышеуказанной программы:
Welcome
Пример 3
В следующем примере мы наблюдаем DSL для запроса данных с использованием SQL-синтаксиса внутри Python.
class demo:
def __init__(x, dataset):
x.dataset = dataset
def where(x, condition):
x.dataset = [item for item in x.dataset if condition(item)]
return x
def select(x, selector):
return [selector(item) for item in x.dataset]
users = [
{"name": "Ram", "age": 10},
{"name": "Ravi", "age": 24},
{"name": "Rahul", "age": 19},
]
result = demo(users).where(lambda u: u["age"] > 18).select(lambda u: u["name"])
print(result)
Вывод вышеуказанной программы:
['Ravi', 'Rahul']
Python
- Работа с MySQL в Python через стандартный DB-API
- Обработка исключений в Python: подробное руководство
- Hello World: создание вашего первого Python-приложения
- Кортежи в Python: создание, доступ и продвинутые операции
- Мастерство отладки Python: эффективные техники и лучшие практики
- Python против Ruby: подробное сравнение особенностей, преимуществ и сценариев использования
- Множественное, многоуровневое наследование и порядок разрешения методов (MRO) в Python
- Освоение функций Python: определение, вызов, отступы, аргументы и возвращаемые значения
- Переименование файлов и директорий в Python с os.rename() — пошаговое руководство
- Мастерство работы со списками Python: append, sort, len и list comprehensions — практическое руководство