** kwargs в Python нетерпеливы или ленивы? - PullRequest
0 голосов
/ 28 июля 2011

Я пытаюсь выполнить запрос 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 ]

5 голосов
/ 28 июля 2011

В python выражения всегда оцениваются с нетерпением.В питоне нет ленивых вычислений.Некоторые библиотеки обходят отсутствие этой полезной функции, позволяя значениям, которые должны быть определенного типа, вместо этого быть строкой, которая позже eval s.Таким способом можно объявить некоторые части модели django (чтобы можно было объявлять взаимно ссылочные отношения внешнего ключа), но интерфейс запросов django этого не делает.Обычно вы не сможете использовать такую ​​технику, когда строка «ожидаема», потому что у вас не будет возможности отличить строковые значения от строк, которые должны быть eval ed.

0 голосов
/ 28 июля 2011

Я не уверен, что этот вопрос вызван тем, что вам любопытно или вы пытаетесь найти способы загрузки запросов.Поэтому я сделаю предположение:

Я бы использовал функцию Q () и, возможно, загрузил бы их в аргументы, чтобы позже использовать для установки их в 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.

Вот документация , если вы хотите ее проверить.

Этот запрос не будет выполнен, пока вы не запросите информацию, поэтому он будет ленивым.Я имею в виду, пока вы не сделаете что-то вроде

myquery = mylolfunc(*args)
myquery[0]  #-----> executes query here
0 голосов
/ 28 июля 2011

Аргументы функции оцениваются перед вызовом функции:

>>> 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 голосов
/ 28 июля 2011

Только первый правильный:

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

Я не понимаю, как ленивый / нетерпеливый относится к этому вопросу.

...