2011-07-28 10 views
0

私は、Djangoのクエリを実行しようとしている:これが正しいかどう** Pythonの** kwargsは熱心で怠惰ですか?

#att.name is a string 
kwargs = {att.name : F('node__product__' + att.name) } 
temps = Temp.objects.exclude(**kwargs) 

私は思ったんだけど。私が今までに見たすべての例では、値に文字列を使用していますが、値が関数であれば、値を文字列にする必要がありますか?

kwargs = {att.name : 'F('node__product__' + att.name)' } 

値の中の関数が引数リストで賢く実行されるか、必要になるまで待つのですか?

+1

何も起こっていません。 2番目のフォームは解析さえしません。 –

+1

あなたが* '*' * 'を意味するのは合理的でしょうか?' kwargs = {att.name: "F( 'node__product__' + att.name)"} '? – SingleNegationElimination

答えて

5

Pythonでは、式は常に熱心に評価されます。 Pythonには怠惰な評価はありません。いくつかのライブラリは、特定のタイプの値を文字列にすることを可能にすることで、この便利な機能がないことを回避します。これは後でevalとなります。 djangoモデルのいくつかの部分をこのように宣言することができます(相互参照の外部キー関係を宣言することができます)。しかし、djangoのクエリインタフェースはそうではありません。文字列が "期待されている"ときには通常、この種のテクニックを使用することはできません。なぜなら、文字列の値をevalである文字列と区別する方法がないからです。

+3

lambda関数または関数オブジェクトを渡して、遅延評価をシミュレートすることができます。これは、評価されている文字列を作成するよりも好ましい方法です。 –

+0

"純度"の理由から好ましいかもしれませんが、 "Foo.bar"は 'lambda:Foo.bar'よりも読みやすく、理想的な' Foo.bar'に近いです。あなたが期待する文字列の種類を知っていれば、 'eval'を避けることができます。 – SingleNegationElimination

+2

ジェネレータとジェネレータの式が「遅れて」評価されるという議論があります。 – senderle

0

だけ最初のものは正しいです:

kwargs = {att.name : F('node__product__' + att.name) } 
temps = Temp.objects.exclude(**kwargs) 

私はこの質問に関連してどのように怠惰/熱心に理解していません。

0

関数の引数は、関数が呼び出される前に評価されます。

>>> def foo(x): return x 
...: 

>>> foo(sum(range(10))) 
<<< 45 

あなたは辞書のすべてを作成

は、その時点で評価されますので、

>>> kwargs = {'key': sum(range(10))} 

>>> kwargs 
<<< {'key': 45} 

...

>>> def foo(**kwargs): return kwargs 
...: 

>>> foo(**kwargs) 
<<< {'key': 45} 
0

私はこの質問があなたが好奇心を持っているかどうか、あるいはあなたがロードクウェー。だから私は推測がかかります。

私はQ()関数を使用して、多分後でTemp.objects.exclude上でそれらを設定するために使用する引数にそれらをロードされるだろう、このようなものになるだろう:

クエリがQ(att.name = F( 'node_ 製品 _' + att.name))であるか、Qオブジェクトの多くの
def mylolfunc(self, *args,**kwargs): 
    queryset = Q() 
    for query in args: 
     queryset |= query 
return Temp.objects.filter(queryset) 

あなたがチェックアウトしたい場合はここにdocumentationがあります。

このクエリは、情報を要求するまで実行されないため、怠け者になります。あなたが何かをするまで、私はあなたが何かをするまでを意味する

myquery = mylolfunc(*args) 
myquery[0] #-----> executes query here 
関連する問題