Pony ORM делает хороший трюк преобразования выражения генератора в SQL. Пример:
>>> select(p for p in Person if p.name.startswith('Paul'))
.order_by(Person.name)[:2]
SELECT "p"."id", "p"."name", "p"."age"
FROM "Person" "p"
WHERE "p"."name" LIKE "Paul%"
ORDER BY "p"."name"
LIMIT 2
[Person[3], Person[1]]
>>>
Я знаю, что у Python есть замечательная интроспекция и метапрограммирование, но как эта библиотека может переводить выражение генератора без предварительной обработки? Это похоже на волшебство.
[обновление]
Блендер писал (а):
Вот файл, который вам нужен. Кажется, реконструирует генератор с помощью какого-то маневра интроспекции. Я не уверен, поддерживает ли он 100% синтаксиса Python, но это довольно круто. - Блендер
Я думал, что они изучают некоторые функции из протокола выражения генератора, но просматривают этот файл и видят, что модуль ast
задействован... Нет, они не проверяют источник программы на лету, не так ли? Умопомрачительных...
@BrenBarn: если я пытаюсь вызвать генератор вне вызова функции select
, результат:
>>> x = (p for p in Person if p.age > 20)
>>> x.next()
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<interactive input>", line 1, in <genexpr>
File "C:\Python27\lib\site-packages\pony\orm\core.py", line 1822, in next
% self.entity.__name__)
File "C:\Python27\lib\site-packages\pony\utils.py", line 92, in throw
raise exc
TypeError: Use select(...) function or Person.select(...) method for iteration
>>>
Похоже, они делают больше загадочных заклинаний, таких как проверка вызова функции select
и обработка летнего дерева грамматики синтаксиса Python.
Я все еще хотел бы, чтобы кто-то объяснил это, источник выходит за рамки моего уровня волшебства.