Definição de uma função

As funções devem ser indentadas como qualquer controle de fluxo.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def test():
    print('isso é uma função')

test()

[/pastacode]

Declaração de retorno

As funções podem, opcionalmente, retornar valores.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def circulo(raio):
    return 3.14 * raio * raio

print circulo(1.5)

[/pastacode]

Por padrão, as funções retornam none.

Observe a sintaxe para se definir uma função:

  • a palavra chave def;
  • seguida pelo nome da função;
  • e os argumentos da função, colocados entre parenteses, separador por vírgulas e fechando com dois pontos;
  • o corpo da função;
  • e o retorno com return objeto para opcionalmente retornar valores.

Parâmetros

Parâmetros obrigatórios (parâmetros de posição):

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def duplique(x):
    return x * 2

print duplique(3)
print duplique()    #dará erro indicando que falta um parâmetro

[/pastacode]

Parâmetros opcionais (palavras chaves ou argumentos nomeados):

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def duplique(x=2):
    return x * 2

print duplique(3)
print duplique()    #utiliza o valor estabelecido no parâmetro

[/pastacode]

Argumentos palavras chave permitem especificar valores padrões.

ATENÇÃO: Valores padrões são avaliados quando a função é definida, não quando é chamada. Isso pode ser um problema quando se usa tipos mutáveis (como dicionários ou listas) e modificá-los no corpo da função, sendo que as modificações irão persistir durante a chamada dos códigos da função.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

grande = 10

def duplique(x=grande):
    return x * 2

grande = 1e9

print duplique()

[/pastacode]

Um exemplo mais completo, utilizando o corte do python:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def corte(seq, inicio=None, fim=None, inc=None):
    """Implementação do corte básico do python"""
    return seq[inicio:fim:inc]

frase = 'um peixe, dois peixes, peixe vermelho, peixe azul'.split()

[/pastacode]

A partir daqui, implemente no console interativo:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

frase corte(frase)
corte(frase, inc=2)
corte(frase, 1, inc=2)
corte(frase, inicio=1, fim=4, inc=2)

[/pastacode]

A ordem dos argumentos palavra chave não importa:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

corte(frase, inc=2, inicio=1, fim=4)

[/pastacode]

Mas, é boa prática manter a mesma ordem definida na função.

Argumentos palavra chave são uma característica muito conveniente para a definição de funções com um número variável de argumentos, especialmente quando valores padrões precisam ser utilizados na maioria das vezes na chamada da função.

Passagem por valor

É possível modificar um valor de uma variável dentro de uma função? A maioria das linguagens (C, java…) fazem distinção de uma passagem por valor e por referência. No Python, tal distinção é, de certa forma, artificial, e é um pouco sutil quando suas variáveis serão modificadas ou não. Felizmente, existem regras claras.

Parâmetros para funções são referências à objetos que são passados por valor. Quando se passa uma variável a uma função, o python passa a referência ao objeto ao qual a variável se refere (o valor), e não a variável propriamente dita.

Se o valor é imutável, a função não modifica a variável chamada. Se o valor é mutável, a função pode modificar a variável chamada.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def modificar(x, y, z):
    x = 23
    y.append(42)
    z = [99] # nova referencia
    print(x)
    print(y)
    print(z)

a = 77    # variável imutável
b = [99]  # variável mutável
c = [28]
modificar(a, b, c)

print(a)
print(b)
print(c)

[/pastacode]

Funções possuem uma tabela de variáveis locais chamada de namespace local.

A variável x, por exemplo, somente existe dentro da função modificar.

Variáveis globais

Variáveis declaradas fora da função podem ser utilizadas dentro da função.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

x = 5

def somax(y):
    return x + y

print somax(10)

[/pastacode]

Essas variável não podem ser modificadas dentro da função, a não ser que sejam declaradas globais na função.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

x = 5
def facax(y):
    x = y
    print('x is

facax(10)
print x

[/pastacode]

Assim deve funcionar:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

x = 5
def facax(y):
    global x
    x = y
    print('x is

facax(10)
print x

[/pastacode]

Número de parâmetros variáveis

Formas especiais de parâmetros:

  • *args: qualquer número de argumentos posicionais empacotados em uma tupla.
  • **kwargs: qualquer número de argumentos palavra chave empacotados em um dicionário.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def args_variaveis(*args, **kwargs):
    print 'args são', args
    print 'kwargs são', kwargs

args_variaveis('um', 'dois', x=1, y=2, z=3)

[/pastacode]

Docstrings

Docstring é a documentação sobre o que a função faz e seus parâmetros. Convenção geral:

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def nomefuncao(parametros):
    """Descrição da função e de seus parâmetros.
    Escreva de forma objetiva para ser rápidamente entendido.
    """
    # corpo da função
    pass

print nomefuncao(parametro) #observe a doctring mostrada no object inspector

[/pastacode]

Construção de Docstrings:

Para uma padronização, foram definidas a semântica e certas convenções associadas as docstrings do Python, que podem ser consultadas em Docstring Conventions.

Os módulos Numpy e Scipy definiram um padrão preciso para a documentação das funções científicas, que você talvez queira utilizar em suas próprias funções, utilizando seções de parâmetros, exemplos, etc. Veja em https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt e http://projects.scipy.org/numpy/browser/trunk/doc/example.py#L37.

Funções são objetos

Funções são objetos de primeira classe, o que significa que elas podem ser:

  • atribuídas a uma variável;
  • um item em uma lista (ou qualquer recipiente);
  • passadas como um argumento para outra função.

[pastacode lang=”python” message=”” highlight=”” provider=”manual”]

def args_variavel(*args, **kwargs):
    print 'args é', args
    print 'kwargs é', kwargs

va = args_variavel

va('três', x=1, y=2)

[/pastacode]

Métodos

Métodos são funções anexadas à objetos, como já visto com as listas, dicionários, strings, etc.