118

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 には素晴らしいイントロスペクションとメタプログラミングが組み込まれていることは知っていますが、このライブラリはどのようにして前処理なしでジェネレータ式を変換できるのでしょうか? それは魔法のように見えます。

[アップデート]

ブレンダーは次のように書いています。

これがあなたが求めているファイルです。イントロスペクションの魔法を使ってジェネレーターを再構築しているようです。Python の構文を 100% サポートしているかどうかはわかりませんが、これはかなりクールです。– ブレンダー

彼らはジェネレータ式プロトコルの機能を調査していると思っていましたが、このファイルを見て、関連する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 抽象構文文法ツリーをその場で処理したりするなど、より難解な呪文を実行しているようです。

私はまだ誰かがそれを説明してくれるのを見たいと思っています.ソースは私の魔法のレベルをはるかに超えています.

4

1 に答える 1