¿Cómo hace Pony (ORM) sus trucos?
Pony ORM hace el buen truco de convertir una expresión del generador en SQL. Ejemplo:
>>> 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]]
>>>
Sé que Python tiene una introspección y metaprogramación maravillosas integradas, pero, ¿cómo esta biblioteca puede traducir la expresión del generador sin preprocesamiento? Parece magia.
[actualizar]
Blender escribió:
Aquí está el archivo que estás buscando Parece reconstruir el generador usando alguna magia de introspección. No estoy seguro de si es compatible con el 100% de la sintaxis de Python, pero esto es bastante bueno. - Licuadora
Estaba pensando que estaban explorando alguna característica del protocolo de expresión del generador, pero mirando este archivo y viendo elast
módulo involucrado ... No, no están inspeccionando la fuente del programa sobre la marcha, ¿verdad? Alucinante ...
@BrenBarn: Si intento llamar al generador fuera delselect
Llamada de función, el resultado es:
>>> 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
>>>
Parece que están haciendo más encantamientos arcanos como inspeccionar elselect
Llamar a la función y procesar el árbol de gramática de sintaxis abstracta de Python sobre la marcha.
Todavía me gustaría ver a alguien explicándolo, la fuente está muy por encima de mi nivel de magia.