Python中的**kwargs是急切还是延迟?

0 投票
4 回答
799 浏览
提问于 2025-04-16 22:24

我正在尝试执行一个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

函数的参数在调用函数之前就会被计算出来:

>>> 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

只有第一个是正确的:

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

我不明白“懒惰”和“急切”跟这个问题有什么关系。

5

在Python中,表达式总是会被立即计算,也就是说没有懒惰计算的概念。懒惰计算是指只有在需要的时候才计算的方式。为了弥补这个缺点,有些库允许本来应该是特定类型的值变成字符串,然后再用eval来计算它。你可以用这种方式在Django模型中声明一些部分(这样可以声明互相引用的外键关系),但Django的查询接口不支持这种做法。通常情况下,当期待一个字符串时,你无法使用这种技巧,因为你无法区分哪些字符串是普通的字符串,哪些是需要用eval来计算的。

撰写回答