Ir para o conteúdo
ou

Software livre Brasil

Magnun

Nenhum artigo selecionado ainda.
 Voltar a Blog
Tela cheia

[Curso de Python] Ultima Palavra Sobre Argumentos de Funções

23 de Agosto de 2010, 0:00 , por Software Livre Brasil - 0sem comentários ainda | Ninguém está seguindo este artigo ainda.
Visualizado 199 vezes

Antes de prosseguir leia os artigos anteriores aqui



Olé pessoal! Estamos de volta com mais uma aula deste curso de introdução ao Python. Nesse post vou falar basicamente sobre alguns detalhes relevantes às variáveis utilizadas nos argumentos de funções.


Ultima Palavra Sobre Argumentos de Funções



Quando trabalhamos com argumentos de funções começamos a entrar em dúvida sobre as variáveis utilizadas. Então vamos ressaltar alguns comportamentos e dicas sobre os argumentos de funções.

1. Primeiro ponto a ressaltar é que a função do argumento não precisa ter o mesmo nome que a variável do argumento. Pode parecer lógico mas este tipo de dúvida ocorre:

Código:
>>> def teste(f_var1):
...     print f_var1
...
>>> var1 = 12
>>> var2 = 20
>>> teste(var1)
12
>>> teste(var2)
20
>>>
2. A variável passada para função é a mesma utilizada dentro da função. Complicou?! Olhando o exemplo acima, a variável var1 passada para a função teste é a mesma variável f_var1. Quer uma prova disso? Basta usar a função id:

Código:
>>> def teste_id(var):
...     print 'Identificador na função:',id(var)
... 
>>> var1 = 'teste1'
>>> print 'Identificador global:',id(var1)
Identificador global: 3078433056
>>> teste_id(var1)
Identificador na função: 3078433056
>>> var2 = [1, 2, 3]
>>> print 'Identificador global:',id(var2)
Identificador global: 3078433568
>>> teste_id(var2)
Identificador na função: 3078433568
>>>
Como podemos ver, a variável é sempre a mesma. Agora vamos fazer uma pequena brincadeira:

Código:
>>> def altera_texto(texto):
...     texto = '(' + texto + ')'
...     print 'texto em funcao:',texto
...
>>> texto1 = 'teste'
>>> altera_texto(texto1)
texto em funcao: (teste)
>>> print 'texto global:',texto1
texto global: teste
>>>
Se a variável é sempre a mesma, então porque quando alteramos o valor da variável texto a outra variável texto1 não se alterou?. Essa é uma explicação simples mas complexa, se é que isso é possível. Em Python, conforme já havíamos comentado, os tipos (int, float, list, tuple e etc) podem ser classificados em 2 tipos: mutáveis e imutáveis. Os tipos mutáveis são aqueles que podem ser alterados como listas e dicionários, enquanto os imutáveis são queles que seus valores não podem ser alterados, inteiros, complexos, longos, ponto flutuante, tuplas e booleanos. Quando tentamos alterar o valor de um tipo imutável, o que realmente ocorre é a criação de uma nova variável.

As variáveis em Python funcionam como ponteiros, elas apontam para uma posição de memoria, inclusive o número mostrado pela função id, é o endereço de memória daquela variável. Quando fazemos x = 1, criamos o valor estático 1 e apontamos para ela a variável x. Quanto fazemos x = 2, o valor 1 é descartado e o valor 2 é criado, x passa a apontar para essa nova posição de memoria.

Ok, então vamos ver agora como o Python se comporta quando alteramos valores de tipos mutáveis, neste exemplo utilizarei o método append das listas. Esse método adiciona um novo item:

Código:
>>> def altera_lista(lista):
...     lista.append('novo item')
...     print 'lista da função:',lista
... 
>>> lista1 = ['item', 'outro item']
>>> altera_lista(lista1)
lista da função: ['item', 'outro item', 'novo item']
>>> print 'lista global:',lista1
lista global: ['item', 'outro item', 'novo item']
>>>
Como podemos ver, ambas as variáveis foram alteradas. Isso ocorre porque não temos re-atribuição de variável apenas alteramos a variável existente.


3. Variáveis criadas dentro de funções não podem ser acessadas externamente. Isso ocorre devido ao escopo de variáveis que será explicado com detalhes mais a frente. Vamos ao exemplo:

Código:
>>> def teste(var):
...     valor = var + 10
... 
>>> teste(10)
>>> print valor
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'valor' is not defined
>>>
4. Argumentos pre-definidos podem ter dar dor de cabeça. Só tem uma forma de explicar isso, através de um exemplo:

Código:
>>> def altera_lista(lista=[4, 5, 6]):
...     lista.append(10)
...     print lista
... 
>>> altera_lista([1, 2, 3])
[1, 2, 3, 10]
>>> altera_lista([1, 2, 3])
[1, 2, 3, 10]
>>> altera_lista([1, 2, 3])
[1, 2, 3, 10]
>>>
>>> altera_lista()
[4, 5, 6, 10]
>>> altera_lista()
[4, 5, 6, 10, 10]
>>> altera_lista()
[4, 5, 6, 10, 10, 10]
>>>
A primeira chamada (altera_lista([1, 2, 3])) não nos surpreende e retorna sempre o valor esperado, a lista passada como argumento com um novo item (o valor 10). á as execuções utilizando o argumento padrão (com exceção da primeira chamada) está completamente o oposto do que deveria ser. Isto ocorre pois a variável padrão é iniciada apenas no início do programa, e toda vez que a alteramos este valor é armazenado para a próxima execução. O melhor modo de ter o comportamento esperado é inciar uma nova lista, da seguinte forma:

Código:
>>> def altera_lista(lista=[4, 5, 6]):
...     lista = lista[:]
...     lista.append(10)
...     print lista
... 
>>> altera_lista()
[4, 5, 6, 10]
>>> altera_lista()
[4, 5, 6, 10]
>>> altera_lista()
[4, 5, 6, 10]
>>>
O lista[:] está simplesmente criando uma cópia da lista e atribuíndo-a para a variável lista. Durante essa execução esse será o valor de lista, quando a função for chamada novamente ela "apontará" a variável lista de volta para o valor padrão de [4, 5, 6].

Não se esqueçam que as variáveis em Python são meros ponteiros, com isso em mente será mais fácil entender e prever esse tipo de comportamento.

Até a próxima...

Fonte: http://under-linux.org/blogs/magnun/%5Bcurso-de-python%5D-ultima-palavra-sobre-argumentos-de-funcoes-2217/

0sem comentários ainda

Enviar um comentário

Os campos são obrigatórios.

Se você é um usuário registrado, pode se identificar e ser reconhecido automaticamente.