Lazy evaluation em python com django
Uma experiência frustrada tentando usar Lazy Evaluation no Python, com o framework Django.
Em Python há uma sutil diferença entre essa construção:
colchetes = [x for x in range(10)]
E essa:
parenteses = (x for x in range(10))
Sutil na sintaxe, mas profunda no que representam.
Inspecionemos a construção com colchetes:
>>> colchetes.__class__
<class 'list'>
>>> colchetes
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
E inspecionemos a com parenteses:
>>> parenteses.__class__
<class 'generator'>
>>> parenteses
<generator object <genexpr> at 0x7f7395b36938>
Em programas simples, elas podem simplesmente ser substituídas por um loop for:
>>> loopfor = []
>>> for x in range(10): loopfor.append(x)
>>> loopfor
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Por curiiosidade, o que é um range
afinal?
>>> usandorange = range(10)
>>> l
>>> usandorange
range(0, 10)
usandorange(0, 10)
>>> l[1]
1
>>> usandorange.__class__
<class 'range'>
>>> dir(usandorange)
['__class__', '__contains__', '__delattr__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__',
'__init__', '__iter__', '__le__', '__len__', '__lt__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__reversed__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'count', 'index', 'start',
'step', 'stop']
Ainda estou voando. Investigando mais um pouco:
>> print(usandorange.__doc__)
range(stop) -> range object
range(start, stop[, step]) -> range object
Return an object that produces a sequence of integers from start (inclusive)
to stop (exclusive) by step. range(i, j) produces i, i+1, i+2, ..., j-1.
start defaults to 0, and stop is omitted! range(4) produces 0, 1, 2, 3.
These are exactly the valid indices for a list of 4 elements.
When step is given, it specifies the increment (or decrement).
Cheguei a esse código:
def list_posts(request):
"""List posts."""
try:
posts = blog.models.Post.objects\
.defer('content')\
.all()\
.order_by('-pub_date')
data = {
'status': 'success',
'message': '',
'posts': [post_info(request, post) for post in posts],
}
except:
return fail('Internal error. Please, try later.', 503)
data['posts_count'] = len(data['posts'])
return JsonResponse(data)