[Curso de Python] Ultima Palavra Sobre Argumentos de Funções
23 de Agosto de 2010, 0:00 - sem comentários aindaAntes 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...
Repercussão do Curso de Python
18 de Agosto de 2010, 0:00 - sem comentários aindaEditar um curso dentro da comunidade Under-Linux é muito legal. Vejo a resposta de diversas pessoas que acompanho o curso e me sinto "gratificado" por saber que estou ajudando tanta gente e por ver que tantas pessoas estão interessadas no que escrevo.
Apesar do tamanho da nossa comunidade ela não se compara com o resto da internet, por isso me senti muito muito "gratificado" esses dias quando recebi um link do Sérgio Berloto, do blog Programando Python no RS. Para quem quiser ver o comentário dele a cerca do Curso de Python o link está aqui: Curso de Pyhon - Programando Python no RS
Não sei em que circunstâncias ele caiu aqui (provavelmente) pelo Google mas se ele me linkou é porque eu devo ter quebrado um galho pra ele :). Então estou retribuindo o favor...
Então quem gosta de Python e principalmente Django, vale a pena conferir esse blog pois tem muito conteúdo interessante, além do cara ser apreciador de Heavy Metal, o que já o fez ganhar um leitor através do GoogleReader :D.
Update: Acabei de ver que o cara ta editando um livro gratúito sobre ArchLinux!
Até mais...
[Curso de Python] Funções que Retornam Valores - Parte 2/2
18 de Agosto de 2010, 0:00 - sem comentários aindaAntes de prosseguir leia os artigos anteriores aqui
Olá pessoal! Hoje não tem muito blah blah blah, vamos fechar o conceito do "comando" return para podermos ver conceitos mais avançados com as funções em Python.
Funções que Retornam Valores - Parte 2/2
Conformefalamos na última aula, o comando return pode retornar qualquer tipo de dados. Diferente de outras linguagens o Python não restringe o tipo da variável de retorno, como ocorre em linguagens como C/C++, Java e etc. Vamos a um exemplo simples:
Como mostrado acima, uma única função pode retornar diversos diversos tipos diferentes.Código:>>> def retorna(tipo): ... if tipo == 'int': ... return 1 ... elif tipo == 'long': ... return 1L ... elif tipo == 'float': ... return 1.5 ... elif tipo == 'complex': ... return 1 + 2j ... elif tipo == 'list': ... return [1,2,3] ... elif tipo == 'tuple': ... return (1,2,3) ... elif tipo == 'dict': ... return {'a':1, 'b':2} ... >>> >>> retorna('int') 1 >>> retorna('long') 1L >>> retorna('float') 1.5 >>> retorna('complex') (1+2j) >>> retorna('list') [1, 2, 3] >>> retorna('tuple') (1, 2, 3) >>> retorna('dict') {'a': 1, 'b': 2} >>>
Muitas pessoas se espantam quando vêem códigos em Python que retornam mais de uma variável. Devido à maleabilidade do Python, você pode fazer códigos estranhos como esse:
Quando olhamos rapidamente o código acima temos q impressão de que o comando return no Python é capaz de retornar mais de uma variável (nesse exemplo o booleano True e o inteiro 2), mas isso não passa de uma "ilusão" pois quando chamamos a função e passamos o seu valor para uma única variável, vemos que na verdade foi retornado uma tupla com dois valores. Dessa forma, utilizar o "return True, 2" é o mesmo que "return (True, 2)". Pessoalmente prefiro utilizar os parênteses para ficar claro que aquilo é uma tupla, não correndo o risco de gerar uma dupla interpretação sobre o código.Código:>>> def teste(): ... return True, 2 ... >>> flag, numero = teste() >>> flag True >>> numero 2 >>> x = teste() >>> print x (True, 2) >>> type(x) <type 'tuple'> >>>
Até a próxima pessoal...
[Curso de Python] Funções que Retornam Valores - Parte 1/2
11 de Agosto de 2010, 0:00 - sem comentários aindaAntes de prosseguir leia os artigos anteriores aqui
Olá pessoal! Revendo algumas das nossas últimas aulas sobre funções percebi que havia esquecido de abordar o assunto de funções que retornam valores. Então vamos voltar um pouco nos conceitos mais avançados de funções e vamos ver um conceito mais básico, o "comando" return.
Funções que Retornam Valores - Parte 1/2
Muitas vezes criamos funções para simplificar e modularizar o nosso código. Muitas dessas organizações consistem em funções que realizam algum processamento que pode vir a ser repetido diversas vezes. O "comando" return torna possível que uma função retorne um valor. Esse valor pode ser útil para uma outra parte do programa e pode ser guardado em uma variável. Em Python, não há restrições quanto ao tipo do valor a ser retornado. Vamos a um exemplo básico, uma função que diz se o argumento é uma string ou não. Nesse exemplo, vou utilizar a função type, para quem não lembra como ela funciona vale uma revisão na seguinte aula: [Curso de Python] Comparando os tipos de variáveis
Nesse exemplo, vemos como o return funciona de forma diferente de um "comando" comum. na função eh_str2 utilizamos o print para mostrar o fluxo do programa. Quando o programa entra no if ele imprime 'eh str', depois sai do if e executa o print 'nao eh str'. Já quando utilizamos o return na função eh_str vemos que quando ele entra no if ele nunca sai, pois o comando return quebra toda a execução da função e retorna para o ponto onde a função foi chamada. Vamos ver agora o mesmo exemplo mas com o valor retornado sendo armazenado em uma variável:Código:>>> def eh_str(arg): ... if type(arg) is str: ... return True ... return False ... >>> >>> def eh_str2(arg): ... if type(arg) is str: ... print 'eh str' ... print 'nao eh str' ... >>> >>> eh_str(12) False >>> eh_str('teste') True >>> eh_str([1,2]) False >>> >>> eh_str2(12) nao eh str >>> eh_str2('teste') eh str nao eh str >>> eh_str2([1,2]) nao eh str >>>
Podemos notar que o return "envia" de volta uma variável, nesse caso o booleano True. No caso da função eh_str2, como não retornamos nenhuma variável, por padrão é retornado a variável None, o valor nulo utilizado pelo Python.Código:>>> def eh_str(arg): ... if type(arg) is str: ... return True ... return False ... >>> >>> def eh_str2(arg): ... if type(arg) is str: ... print 'eh str' ... print 'nao eh str' ... >>> >>> ret = eh_str('teste') >>> print ret,type(ret) True <type 'bool'> >>> ret = eh_str2('teste') eh str nao eh str >>> print ret,type(ret) None <type 'NoneType'> >>>
Nesse próximo exemplo, vou utilizar o operador in, para quem não lembra como ele funciona basta consultar essa aula: [Curso de Python] Condições com o operador in
Como podemos ver, no código a função valida texto itera sobre cada letra do texto informado verificando se ela está na variável CARACTERES_VALIDOS. Caso não esteja (if letra not in CARACTERES_VALIDOS) ele retorna o valor falso. O comando return automaticamente sai da função, cancelando toda sua execução, dessa forma ele não itera sobre o restante das letras.Código:# Este programa verifica se o texto # informada possui apenas letras e espaços # Esta variável possui todos os caracteres válidos CARACTERES_VALIDOS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVwXYZ ' def valida_texto(texto): for letra in texto: if letra not in CARACTERES_VALIDOS: return False return True while True: texto = raw_input('Informe um texto (para sair digite "sair"): ') if texto == 'sair': break retorno = valida_texto(texto) if retorno: print 'Texto validado' else: print 'Texto inválido!' print 'Até a próxima...'
Caso ele não entre no if nenhuma vez durante a iteração temos a certeza que todas as letras são válidas, com isso retornamos o valor True. No loop while recebemos o texto com a função raw_input e verificamos se foi digitado 'sair. Caso positivo, saímos do loop com o comando break. Em seguida chamamos a função valida_texto e armazenamos seu retorno na variável 'retorno'. Dependendo do retorno imprimimos uma mensagem para o usuário e no final emitimos a mensagem de finalização do programa. Vamos ver um exemplo de execução:
Nos testes vemos que as frases com acentos, números e qualquer outro caractere que não sejam as letras de a-z e A-Z, será mostrada a mensagem "Texto inválido!".Código:Informe um texto (para sair digite "sair"): este é um teste Texto inválido! Informe um texto (para sair digite "sair"): este eh 1 teste Texto inválido! Informe um texto (para sair digite "sair"): este eh um teste Texto validado Informe um texto (para sair digite "sair"): sair Até a próxima...
Até a próxima...
[Curso de Pyhon] Índice
4 de Agosto de 2010, 0:00 - sem comentários aindaOlá pessoal!
Conforme já foi noticiado pelo Under-Linux, estou editando um curso de Python. Como ele está se tornando bem grande, resolvei criar essa página de índice para o curso. Dessa forma fica mais fácil para as pessoas localizarem o conteúdo desejado e também ver até onde o curso já chegou.
Curso de Python
Aula 001 - Primeiros Passos
Aula 002 - Python Interativo
Aula 003 - Strings - Parte 1
Aula 004 - Strings - Parte 2
Aula 005 - Introdução à Tuplas e Lístas
Aula 006 - Introdução: Dicionários
Aula 007 - Introdução - Variaveis
Aula 008 - O Que é slicing?!
Aula 009 - Slicing em strings
Aula 010 - Slicing em Tuplas e Listas
Aula 011 - Produzindo saídas - parte 1
Aula 012 - Produzindo saídas - parte 2
Aula 013 - Interação com o usuário - Parte 1
Aula 014 - Interação com o usuário - Parte 2
Aula 015 - Interação com o usuário - Parte 3
Aula 016 - Condições e if
Aula 017 - Estruturas if, else e elif
Aula 018 - Mais um pouco sobre if/elif/else
Aula 019 - Atribuição condicional
Aula 020 - Condições com o operador in
Aula 021 - Comparando os tipos de variáveis
Aula 022 - Condições com variáveis vazias
Aula 023 - A estrutura while
Aula 024 - Exercícios com o while (correção)
Aula 025 - while else
Aula 026 - Estrutura while: continue e break
Aula 027 - Mais Sobre as Estruturas while
Aula 028 - Conhecendo o for... in...
Aula 029 - Entendendo o for
Aula 030 - Estruturas for Aninhadas
Aula 031 - A função range
Aula 032 - Correção: Estruturas For Aninhadas
Aula 033 - O for e Outras Palavras Mais
Aula 034 - Introdução à Funções em Python
Aula 035 - Correção - O for e Outras Palavras Mais
Aula 036 - Funções com Argumentos
Aula 037 - Correção - Funções com Argumentos
Aula 038 - Funções e Argumentos Nomeados
Aula 039 - Funções com Argumentos e Valores Padrões
Aula 040 - Funções Com Argumentos Indefinidos - Parte 1
Aula 041 - Funções Com Argumentos Indefinidos - Parte 2