quarta-feira, setembro 30, 2009

Coisas que eu devo lembrar sobre o Python


Funções com parâmetros  "defaults" para objetos mutáveis .
In [1]: def funcao(x, lista=[]):
   ...:     lista.append(x)
   ...:     return lista
   ...:

In [2]: print funcao('a')
------> print(funcao('a'))
['a']

In [3]: print funcao('b')
------> print(funcao('b'))
['a', 'b']

In [4]: print funcao('c')
------> print(funcao('c'))
['a', 'b', 'c']

In [5]: print funcao('d')
------> print(funcao('d'))
['a', 'b', 'c', 'd']


sendo que o esperado seria

print funcao('d')
>>['d']

print funcao('e')
>>['e']


 como acontece abaixo
In [27]: def funcao(a=0):
   ....:     return a
   ....:

In [28]: funcao(1)
Out[28]: 1

In [29]: funcao(2)
Out[29]: 2

In [30]: funcao()
Out[30]: 0

O problema é que o "default value" é  assinalado uma única vez, e não é quando a função é chamada, mas sim, quando é definida.
Problema parecido acontece quando o default value é um método....

In [66]: def funcao(tempo=time.time()):
   ....:     print tempo
   ....:    
   ....:    

In [67]: funcao
Out[67]: <function funcao at 0x95f9534>

In [68]: funcao()
1254349399.98

In [69]: funcao()
1254349399.98

In [70]: funcao()
1254349399.98

In [71]: funcao()
1254349399.98







caso seja para sempre retornar o valor atualizado, devemos passar a referência à função


In [73]: def funcao(tempo=time.time):
   ....:     print tempo()
   ....:    


In [74]: funcao
Out[74]: <function funcao at 0x95f933c>

In [75]: funcao()
1254349428.79

In [76]: funcao()
1254349429.94

In [77]: funcao()
1254349431.35
 

Os cometários que  explicam este comportamento:

    "The default value is evaluated only once. This makes a difference when the default is a mutable object such as a list, dictionary, or instances of most classes. For example, the following function accumulates the arguments passed to it on subsequent calls:  "

                Guido Van Russel [1] 

ou 

uma discussão sobre o assunto em [2]



Mas se isso é verdade, se o porque do "acúmulo"  da varável é porque os valores defaults bem como variáveis e ou  métodos de uma classe são "atribuidos" uma única vez quando a função é interpretada,  então porque quando definimos def " funcao(x=0): " o problema nao occore não ocorre?



In [81]: def funcao(x=0):
   ....:     x = x+1
   ....:     return x
   ....:

In [82]: funcao(2)
Out[82]: 3

In [83]: funcao(2)
Out[83]: 3

In [84]: funcao(2)
Out[84]: 3




Não está faltando nada no porque ? 
se o valor default da var x, é assinlado somente uma única vez quando a função foi criada, porque ao alterar o valor de x dentro da minha função, também não ocorre o acúmulo? ou porque x não permanece com o último valor como acontece quando passado um método ou uma lista ?


pensando em ponteiros e memória, não consigo imaginar porque o comportamento diferente de uma var ou um metodo ou lista.

quarta-feira, setembro 16, 2009

terça-feira, setembro 15, 2009

django-caching - Aplicação com cache de queryset no django

mmalone’s django-caching
Uma aplicação django que usa "managers" customizados, fields, e querysets para cachear
objetos de uma maneira mais transparent
Mike Malone, disponibilizou uma app utilizada no POWNCE para ter cache de querysets dentro do django.

segunda-feira, setembro 14, 2009

ler dólar do banco central

Função para ler um feed do banco central retornar, Dolar, Taxa de inflação e outros
 import feedparser,sys

def f(data):
    return data.encode("latin1","ignore")

try:
    feed = sys.argv[1]
except IndexError:
    feed = "http://www4.bcb.gov.br/feed/taxas.ashx"

d = feedparser.parse(feed)
print f(d.feed.title),";",f(d.feed.link),";",f(d.feed.subtitle),";",f(d.version),";",f(d.encoding),";",len(d.entries)
for entry in d.entries:
    print f(entry.title),";",
    print f(entry.link),";",
    try:
        print f(entry.author_detail.name),";",
    except AttributeError:
        pass  
    try:
        print f(entry.content)
    except AttributeError:
        pass
    try:
        print f(entry.description)
    except:
        pass
  
    print