开发者

Is **kwargs in Python eager or lazy?

开发者 https://www.devze.com 2023-03-23 05:07 出处:网络
I\'m trying to execute a Django query: #att.name is a string kwargs = {att.name : F(\'node__product__\' + att.name) }

I'm trying to execute a Django query:

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

I'm wondering if this is correct. All the examples I've seen so开发者_运维百科 far use strings in the values, but what if the value is a function, should I make the value a string, like this?

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

Does the function in the value get executed eagerly in the argument list or does it wait until it's needed?


In python, expressions are always evaluated eagerly. There is no lazy evaluation in python. Some libraries get around the absence of this useful feature by allowing values that should be of some specific type to instead be a string, which it later evals. You can declare some parts of a django model this way (so that you can declare mutually referential foreign key relationships), but django's query interface does not. You wouldn't normally be able to use this kind of technique when a string is "expected", because you'd have no way to distinguish string values from strings that should be evaled.


Only the first one is correct:

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

I don't understand how lazy/eager is related to this question.


Function arguments are evaluated before the function is called:

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

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

When you create a dict everything is evaluated at that moment:

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

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

So...

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

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


I am not sure if this question is because you are curious or if you are trying to find ways to load querys. So I will take a guess:

I would be using the Q() function and maybe load them on args to later use a for to set them on the Temp.objects.exclude, would be something like this:

def mylolfunc(self, *args,**kwargs):
    queryset = Q() 
    for query in args:
        queryset |= query
return Temp.objects.filter(queryset)

Where query is a Q(att.name = F('node_product_' + att.name)) or a lot more of Q objects.

Here is the documentation if you want to check it out.

This query will not execute until you ask for information, so it would be lazy. by that I mean until you do something like

myquery = mylolfunc(*args)
myquery[0]  #-----> executes query here
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号