Ver Feed RSS

root@blog:/# chmod o+r *

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

Avalie este Post de Blog

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

Atualizado 23-08-2010 em 21:37 por Magnun

Categorias
Artigos , Artigos , Dicas , Cursos , Curso de Python , Tutoriais

Comentários

  1. Avatar de equantum
    Olá, Magnun.

    Apenas um equívoco:
    Logo antes do 4o bloco de código você escreveu
    "append das tuplas", sendo que você usou listas
    no exemplo. xD

    Até mais!
  2. Avatar de Magnun
    bem observado equantum! Já corrigi, obrigado!
  3. Avatar de cleoson
    Olá Magnun,
    Aqui os conceitos começam (pelo menos pra mim) a ficar um pouquinho mais complicados. Mas nada que não dê pra entender. Acho que pra internalizar esse conhecimento vai ser melhor com a prática.
    Continuo acompanhando o curso, que continua legal, e aguardando a próxima lição.


    Um abraço!
  4. Avatar de Magnun
    Olá cleoson,

    com certeza aora começa a complicar um pouco, mas quando entendermos o escopo das variáveis tudo vai ser mais simples! Qualquer dúvida estou à disposição.

    Até mais...
  5. Avatar de caiohenrique
    Magnun,

    Lhe enviei um e-mail (magnun[I] at[/I] under-linux [I]dot[/I] org) com um problema que espero que o senhor consiga resolver. Aguardo resposta.

    PS: Excelente curso, continue, com certeza é de grande importância para quem quer saber um pouco mais de forma intuitiva.
  6. Avatar de Magnun
    Olá caio, seu e-mail foi respondido.
  7. Avatar de fabraga
    Agooora o bicho começa a pegar... =)

+ Enviar Comentário