Python中的** kwargs是渴望还是懒惰?

时间:2011-07-28 00:07:24

标签: python django lazy-evaluation kwargs

我正在尝试执行Django查询:

#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)' }

值中的函数是否在参数列表中急切执行,还是等到需要它?

4 个答案:

答案 0 :(得分:5)

在python中,总是急切地评估表达式。 python中没有懒惰的评估。有些库通过允许某些特定类型的值替换为字符串来解决缺少此有用功能的问题,稍后会eval。你可以用这种方式声明django模型的某些部分(这样你就可以声明相互引用的外键关系),但是django的查询接口没有。当字符串是“预期的”时,您通常不能使用这种技术,因为您无法区分字符串值和应该eval编辑的字符串。

答案 1 :(得分:0)

只有第一个是正确的:

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

我不明白这个问题是多么懒惰/急切。

答案 2 :(得分:0)

在调用函数之前计算函数参数:

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

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

当你创建一个dict时,那一刻就会被评估:

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

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

因此...

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

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

答案 3 :(得分:0)

我不确定这个问题是因为你好奇还是想要找到加载查询的方法。所以我会猜测:

我将使用Q()函数,并可能将它们加载到args以便以后使用for来在Temp.objects.exclude上设置它们,就像这样:

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

其中查询是Q(att.name = F('node_ product _'+ att.name))或更多Q对象。

如果你想查看它,这是documentation

在您要求提供信息之前,此查询不会执行,因此它会很懒惰。我的意思是,除非你做像

这样的事情
myquery = mylolfunc(*args)
myquery[0]  #-----> executes query here