[Curso de Python] Ultima Palavra Sobre Argumentos de Funções
por
em 23-08-2010 às 17:39 (7475 Visualizações)
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:
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(f_var1): ... print f_var1 ... >>> var1 = 12 >>> var2 = 20 >>> teste(var1) 12 >>> teste(var2) 20 >>>
Como podemos ver, a variável é sempre a mesma. Agora vamos fazer uma pequena brincadeira: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 >>>
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.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 >>>
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:
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.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'] >>>
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:
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 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 >>>
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.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] >>>
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].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] >>>
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...
Comentários
+ Enviar Comentário