About

Swaroop C H is 29 years of age. He is a coder and startupper. He has previously worked at Yahoo!, Adobe, his own startup and Infibeam.

Read more about him

Views
Personal tools
COLLECTION
Collection

Python pt-br:Funcoes

From Notes

Jump to: navigation, search

Contents

Introdução

Funções são pedaços reutilizáveis de programas. Elas permitem dar um nome para um bloco de código e rodá-lo usando seu nome em qualquer lugar do programa, quantas vezes forem necessárias. Isto é conhecido como chamar a função. Nós já usamos muitas funções internas como len e range.

O conceito de função é provavelmente o bloco de construção mais importante de qualquer programa não-trivial (em qualquer linguagem de programação), portanto vamos explorar vários aspectos das funções neste capítulo.

Funções são definidas usando a palavra-chave def. A mesma é seguida pelo seu nome identificador, um par de parênteses que podem conter ou não nomes de variáveis separados por vírgula, e por dois pontos ao final da linha. Em seguida o bloco de código que faz parte desta função. Um exemplo abaixo irá mostrar que isto é realmente muito simples:

Exemplo:

#!/usr/bin/python
# Filename: funcao1.py
 
def digaOla():
    print('Olá Mundo!') # bloco pertencente à função
# Fim da função
 
digaOla() # chamando a função
digaOla() # chamando a função denovo

Output:

   $ python funcao.py
   Olá Mundo!
   Olá Mundo!

Como isto funciona:

Definimos a função chamada digaOla usando a sintaxe como explicado abaixo. Esta função não recebe parâmetros e conseqüentemente não há variáveis declaradas entre parênteses. Para as funções, parâmetros são somente uma entrada que podemos passar diferentes valores e receber resultados correspondentes.

Repare que podemos chamar a mesma função duas vezes, o que significa que não temos que escrever o mesmo código de novo.

Parâmetros da Função

Uma função pode receber parâmetros, que são valores fornecidos à função para que a mesma possa fazer algo útil com os mesmos. Estes parâmetros são como variáveis, exceto que os valores destas variáveis são definidos quando chamamos a função e já estão atribuídos quando a função é executada.

Parâmetros são especificados dentro do par de parênteses na definição da função, separados por vírgulas. Quando chamamos a função, passamos os valores da mesma maneira. Note a terminologia utilizada - os nomes dados na definição da função são chamados de parâmetros enquanto que os valores que fornecemos na chamada da função são chamados de argumentos.

Exemplo:

#!/usr/bin/python
# Filename: func_param.py
 
def printMax(a, b):
    if a > b:
        print(a, 'is maximum')
    else:
        print(b, 'is maximum')
 
printMax(3, 4) # valores literais passados para a função
 
x = 5
y = 7
 
printMax(x, y) # passando variáveis como argumentos

Saída:

   $ python func_param.py
   4 is maximum
   7 is maximum

Como funciona:

Aqui definimos uma função chamada printMax que recebe dois parâmetros chamados a e b. Encontramos o maior número usando um simples comando if..else e então imprimindo o maior número.

No primeiro uso de printMax, nos passamos diretamente os números (argumentos). No segundo, chamamos a função usando variáveis. printMax(x, y) faz com que o valor do argumento x seja atribuído ao parâmetro a e o valor do argumento y atribuído ao parâmetro b. A função printMax funciona da mesma maneira em ambos os casos.


Variáveis Locais

Quando você declara variáveis dentro de uma definição de função, elas não estão relacionadas de forma alguma com outras variáveis com os mesmos nomes usados fora da função, ou seja, variáveis locais em relação à função. Isto é o que se chama de escopo da variável. Todas as variáveis têm o escopo do bloco no qual são declaradas, a partir do ponto da definição do seu nome.

Exemplo:

#!/usr/bin/python
# Filename: func_local.py
 
def func(x):
    print('x is', x)
    x = 2
    print('Variável local x mudou para', x)
 
x = 50
func(x)
print('x continua', x)

Saída:

   $ python func_local.py
   x is 50
   Variável local x mudou para 2
   x continua 50

Como funciona:

Na função, a primeira vez que usamos o valor do nome x, o Python utiliza o valor do parâmetros declarado na função.

Em seguida, atribuímos o valor 2 a x. O nome x é local à nossa função. Então, quando mudamos o valor de x na função, o x definido no bloco principal permanece inalterado.

No último comando print, confirmamos que o valor de x no bloco principal está de fato inalterado.

Usando o comando global

Se você quer atribuit um valor a um nome definido no nível mais alto do programa, ou seja, fora de qualquer tipo de escopo tal como funções ou classes, então você tem que dizer ao Python que o nome não é local, mas sim global. Fazemos isso usando o comando global. É impossível atribuir um valor a uma variável definida fora de uma função sem utilizar o comando global.

Você pode usar os valores dessas variáveis globais definidas fora da função, assumindo que não haja nenhuma variável com o mesmo nome dentro da função. No entanto, isso não é recomendado e deve ser evitado, uma vez que não fica claro para o leitor do programa onde está a definição da variável. Usar o comando global torna claro que a variável foi definida no block mais externo.

Exemplo:

#!/usr/bin/python
# Filename: func_global.py
 
def func():
    global x
 
    print('x é', x)
    x = 2
    print('Variável global x mudou para', x)
 
x = 50
func()
print('O valor de x é', x)

Saída:

   $ python func_global.py
   x is 50
   Variável global x mudou para 2
   O valor de x é 2

Como funciona:

O comando global é usado para declarar que x é uma variável global. Assim, quando vamos atribuir um valor a x dentro da função, essa mudança é refletida quando usamos o valor de x no bloco principal.

Você pode especificar mais de uma variável global usando o mesmo comando global. Por exemplo, global x, y, z.

Usando o comando nonlocal

Vimos acima como acessar variáveis nos escopos local e global. Existe outro tipo de escopo chamado "nonlocal", que é um meio termo entre esses dois tipos de escopo. Escopos nonlocal ocorrem quando se definem funções dentro de funções.

Uma vez que tudo em Python é código executável, você pode definir funções em qualquer lugar.

Vejamos um exemplo:


#!/usr/bin/python
# Filename: func_nonlocal.py
 
def func_outer():
    x = 2
    print('x é', x)
 
    def func_inner():
        nonlocal x
        x = 5
 
    func_inner()
    print('O x local mudou para', x)
 
func_outer()

Saída:

   $ python func_nonlocal.py
   x é 2
   O x local mudou para 5

Como funciona:

Quando estamos dentro de func_inner, o 'x' definido na primeira linha de func_outer não está, relativamente, nem no escopo local, nem no global. Declaramos que estamos usando esse x por meio de nonlocal x e assim temos acesso àquela variável.

Tente trocar o nonlocal x para global x e também remover o comando e observar a diferença de comportamento nesses dois casos.

Valores padrão de argumentos

Para algumas funções, você pode querer que alguns dos seus parâmetros sejam opcionais e usar valores padrão pré-definidos se o usuário não quiser fornecer valores para esses parâmetros. Isto é feito com a ajuda de valores padrão de argumentos. Você pode especificar valores padrão de argumentos para parâmetros colocando o operador de atribuição (=) após o nome do parâmetro na definição da função, seguifo pelo valor padrão.

Note que o valor do argumento padrão dever ser uma constante. Mais precisamente, o valor do argumento padrão deve ser imutável. Isso é explicado em detalhes nos capítulos seguintes. Por enquanto, basta lembrar disso.

Exemplo:

#!/usr/bin/python
# Filename: func_default.py
 
def say(message, times = 1):
    print(message * times)
 
say('Olá')
say('Mundo', 5)

Saída:

   $ python func_default.py
   Olá
   MundoMundoMundoMundoMundo

Como funciona:

A função chamada say é usada para imprimir uma string quantas vezes forem necessárias. Se nós não fornecemos um valor, então, por padrão, a string é impressa apenas uma vez. Conseguimos isso especificando um valor de argumento padrão 1 para o parâmetro times.

No primeiro uso de say, fornecemos apenas a string e ele a imprime uma vez. No segundo uso de say, fornecemos tanto a string quanto o argumento 5 5 determinando que queremos dizer a mensagem 5 vezes.

Importante
Apenas os parâmetros que estiverem no final da lista de parâmetros podem receber valores padrão de argumento, ou seja, você não pode ter um parâmetro com valor de argumento padrão antes de um parâmetro sem um valor de argumento padrão na ordem dos parâmetros declarados na lista de parâmetros da função.
O motivo é que os valores são atribuídos aos parâmetros por posição. Por exemplo, def func(a, b=5) é válido, mas def func(a=5, b) é não válido.

Argumentos Nomeados

Se você tem funções com muitos parâmetros e quer especificar apenas alguns deles, então você pode passar valores para esse parâmetros nomeando-os. Isto é o que chamamos de argumentos nomeados. Usamos o nome (palavra-chave) ao invés da posição (como viemos usando até agora) para especificar os argumentos para a função.

Existem duas vantagens nessa abordagem: primeiro, é mais fácil usar a função, uma vez que não precisamos nos preocupar com a ordem dos argumentos. Segundo, podemos dar valores apenas para os parâmetros que quisermos, desde que os demais tenham valores padrão de argumento.

Exemplo:

#!/usr/bin/python
# Filename: func_key.py
 
def func(a, b=5, c=10):
    print('a é', a, 'e b é', b, 'e c é', c)
 
func(3, 7)
func(25, c=24)
func(c=50, a=100)

Saída:

   $ python func_key.py
   a é 3 e b é 7 e c é 10
   a é 25 e b é 5 e c é 24
   a é 100 e b é 5 e c é 50

Como funciona:

A função chamada func tem um parâmetro sem valores padrão de argumento, seguida por dois parâmetros sem valores padrão de argumento.

No primeiro uso, func(3, 7), o parâmetro a recebe o valor 3, o parametro b recebe o valor 5 e c recebe o valor padrão de 10.

No segundo uso func(25, c=24), a variável a recebe o valor de 25 devido à posição do argumento. Então, o parâmetro c fica com o valor de 24 devido ao nome, ou seja, aos argumentos nomeados. A variável b fica com o valor padrão de 5.

No terceiro uso func(c=50, a=100), utilizamos somente argumentos nomeados para especificar os valores. Note que estamos especificando o valor para o parâmetro c antes do valor do parâmetro a ainda que a tenha sido definido antes de c na definição da função.

Parâmetros VarArgs

TODO
Devo escrever sobre este assunto num capítulo posterior, uma vez que ainda não falamos sobre listas e dicionários?

Às vezes você pode querer definir uma função que possa receber qualquer número de parâmetros. Isso pode ser conseguido usando os asteriscos:

#!/usr/bin/python
# Filename: total.py
 
def total(initial=5, *numbers, **keywords):
    count = initial
    for number in numbers:
        count += number
    for key in keywords:
        count += keywords[key]
    return count
 
print(total(10, 1, 2, 3, vegetables=50, fruits=100))

Saída:

   $ python total.py
   166

Como funciona:

Quando declaramos um parâmetro prefixado com um asterisco, tal como *param, então todos os argumentos posicionais daquele ponto até o final são armazenados numa lista chamada 'param'.

De maneira similiar, quando declaramos um parâmetro prefixado com dois asteriscos, tal como **param, então todos os argumentos nomeados, a partir daquele ponto até o final, serão armazenados em um dicionário chamado 'param'.

Vamos explorar as listas e dicionários em um capítulo mais à frente.

Parâmetros apenas por palavra-chave

Se quisermos especificar que certos parâmetros por palavra-chave estejam disponíveis somente por palavra-chave e não como argumentos posicionais, estes pode ser declarados após um parâmetro marcado com asterisco:

#!/usr/bin/python
# Filename: keyword_only.py
 
def total(initial=5, *numbers, vegetables):
    count = initial
    for number in numbers:
        count += number
    count += vegetables
    return count
 
print(total(10, 1, 2, 3, vegetables=50))
print(total(10, 1, 2, 3))
# Levanta um erro, pois não fornecemos um valor de argumento padrão para 'vegetables'

Saída:

   $ python keyword_only.py
   66
   Traceback (most recent call last):
     File "test.py", line 12, in <module>
   print(total(10, 1, 2, 3))
   TypeError: total() needs keyword-only argument vegetables

Como funciona:

Declarar parâmetros após um parâmetro marcado com asterisco resulta em argumentos apenas por palavra-chave. Se estes argumentos não são fornecidos com um valor padrão, então chamadas à função levantarão um erro se o argumento por palavra-chave não é fornecido, como visto acima.

Se você quer ter apenas parâmetros por palavra-chave mas não precisa de um parâmetro marcado com asterisco, então simplesmente use um asterisco sem qualquer nome, tal como def total(initial=5, *, vegetables).

O comando return

O comando return é usado para retornar da execução de uma função, isto é, sair da função. Podemos, opcionalmente, retornar um valor vindo da função.

Exemplo:

#!/usr/bin/python
# Filename: func_return.py
 
def maximum(x, y):
    if x > y:
        return x
    else:
        return y
 
print(maximum(2, 3))

Saída:

   $ python func_return.py
   3

Como funciona:

A função maximum retornar o maior valor entre os parâmetros, neste caso, os números fornecidos para a função. Ela usa um simples comando if..else para encontrar o maior valor e retorna esse valor.

Note que um comando return sem um valor é equivalente a return None. None é um tipo especial em Python que representa um valor nulo. Por exemplo, é usado para indicar que uma variável não possui nenhum valor quando tem o valor None.

Cada função implicitamente contém um comando return None no final, a menos que você tenha escrito seu seu próprio comando return. Você pode confirmar isso executando a print someFunction() onde a função someFunction não usa o comando return, tal como:

def someFunction():
    pass

O comando pass é usado em Python para indicar um bloco de comandos vazio.

Nota
Existe uma função embutida chamada max que já implementa a funcionalidade 'encontrar máximo'. Portanto, use esta função sempre que possível.

DocStrings

Python possui um recurso chamado strings de documentação, usualmente conhecidas pelo seu nome mais curto, docstrings. DocStrings são uma ferramenta importante da qual você deve fazer uso, uma vez que ela ajuda a documentar o programa e o torna mais fácil de entender. Python has a nifty feature called documentation strings, usually referred to by its shorter name docstrings. DocStrings are an important tool that you should make use of since it helps to document the program better and makes it more easy to understand. Surpreendentemente, podemos até obter a docstring de, digamos, uma função, durante a execução do programa!

Exemplo:

#!/usr/bin/python
# Filename: func_doc.py
 
def printMax(x, y):
    '''Imprime o maior entre dois números.
 
    Os dois valores devem ser inteiros.'''
    x = int(x) # converte para inteiro, se possível
    y = int(y)
 
    if x > y:
        print(x, 'é o máximo')
    else:
        print(y, 'é o máximo')
 
printMax(3, 5)
print(printMax.__doc__)

Saída:

   $ python func_doc.py
   5 é o máximo
   Imprime o maior entre dois números.
       Os dois valores devem ser inteiros.

Como funciona:

Uma string na primeira linha lógica de uma função é o docstring para essa função. Note-se que docstrings também se aplicam a módulos e classes, que vamos aprender sobre nos respectivos capítulos.

A convenção seguida para um docstring é uma string de múltiplas linhas onde a primeira linha começa com uma letra maiúscula e termina com um ponto. Em seguida, a segunda linha fica em branco, seguida de uma explicação detalhada a partir da terceira linha. É fortemente recomendado que você siga esta convenção para todos os seus docstrings em todas as suas funções não-triviais.

Podemos acessar a docstring da função printMax usando o atributo (nome pertencente a) __doc__ (note o duplo sublinhado) da função. Lembre-se que Python trata tudo como um objeto e isso inclui funções. Vamos saber mais sobre os objetos no capítulo sobre classes.

Se você já usou o help() em Python, então você já viu o uso de docstrings! O que ele faz é apenas buscar o atributo __doc__ dessa função e o exibir para você de uma forma elegante. Você pode experimentá-lo na função acima - basta incluir help(printMax) no seu programa. Lembre-se de pressionar a tecla q para sair do help().

Ferramentas automatizadas podem recuperar a documentação do seu programa desta maneira. Portanto, eu recomendo fortemente que você use docstrings para qualquer função não-trivial que você escreva. O comando pydoc que vem com sua distribuição Python funciona de forma semelhante a help() usando docstrings.

Anotações

Funções possuem outra funcionalidade avançada chamada anotações, que são um modo estiloso de anexar informação adicional para cada um dos parâmetros e também para o valor de retorno. Como o interpretador Python não interpreta estas anotações (tal funcionalidade é responsabilidade de bibliotecas de terceiros), pularemos esta funcionalidade desta discussão. Se você está interessado em ler mais sobre anotações, por favor veja a Proposta de Melhoria do Python No. 3107.

Sumário

Vimos vários aspectos das funções mas note que não cobrimos todos os seus aspectos. Entretanto, cobrimos a maioria das funções de Python que você precisará dia após dia.

E seguida, veremos como usar e criar módulos de Python.


Please add your comments by clicking on the 'Discussion' link in the left sidebar.