Jak Pony (ORM) wykonuje swoje sztuczki?
Pony ORM robi fajną sztuczkę polegającą na konwersji wyrażenia generatora na SQL. Przykład:
>>> 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]]
>>>
Wiem, że Python ma wspaniałą wbudowaną introspekcję i metaprogramowanie, ale jak ta biblioteka jest w stanie przetłumaczyć ekspresję generatora bez wstępnego przetwarzania? Wygląda jak magia.
[aktualizacja]
Blender napisał:
Oto plik że jesteś po. Wydaje się, że rekonstruuje generator za pomocą magii introspekcji. Nie jestem pewien, czy obsługuje 100% składni Pythona, ale jest to całkiem fajne. - Blender
Myślałem, że badają jakąś funkcję z protokołu ekspresji generatora, ale patrząc na ten plik i widzącast
zaangażowany moduł ... Nie, nie sprawdzają źródła programu w locie, prawda? Niesamowite ...
@BrenBarn: Jeśli spróbuję wywołać generator pozaselect
wywołanie funkcji, wynikiem jest:
>>> 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
>>>
Wygląda na to, że robią bardziej tajemnicze zaklęcia, takie jak oglądanieselect
wywołanie funkcji i przetwarzanie abstrakcyjnej gramatyki składni Pythona w locie.
Nadal chciałbym, żeby ktoś to wyjaśnił, źródło jest daleko poza moim poziomem magii.