Subsecções

2.6.2 Truques com argumentos

2.6.2.1 Argumentos nomeados

Argumentos podem ser fornecidos à função especificando-se o nome do parâmetro ao qual correspondem. O código abaixo é equivalente à chamada no exemplo anterior:

    a = bar(t="plains")

mas fica explicitamente declarado que o parâmetro corresponde ao argumento t. Normalmente são nomeados argumentos para tornar a leitura do código mais fácil; no entanto, veremos a seguir como são essenciais para utilizar uma das formas de listas de argumentos variáveis.

2.6.2.2 Valores padrão

Uma das funcionalidades mais interessantes nas funções Python é a possibilidade de definir valores padrão:

    def aplica_multa(valor, taxa=0.1):
        return valor + valor * taxa

Neste exemplo, o valor padrão para a variável taxa é 0.1; se não for definido este argumento, o valor padrão será utilizado.

    >>> print aplica_multa(10)
    11.0
    >>> print aplica_multa(10, 0.5)
    15.0

Dica: Não utilize como valor padrão listas, dicionários e outros valores mutáveis; os valores padrão são avaliados apenas uma vez e o resultado obtido não é o que intuitivamente se esperaria.

2.6.2.3 Conjuntos de argumentos opcionais

Uma forma de definir conjuntos de argumentos opcionais utiliza parâmetros `curinga' que assumem valores compostos. Pode ser fornecido um parâmetro cujo nome é prefixado por um símbolo asterisco, que assumirá um conjunto ordenado de argumentos:

    def desculpa(alvo, *motivos):
        d = "Desculpas %s, mas estou doente" % alvo
        for motivo in motivos:
            d = d + " e %s" % motivo
        return d + "."

    >>> desculpa("senhor", "meu gato fugiu", 
    ...          "minha tia veio visitar")

    "Desculpas senhor, mas estou doente e meu gato fugiu e minha
    tia veio visitar."

ou um parâmetro que assume um conjunto de argumentos nomeados, prefixado de dois asteriscos:

    def equipe(diretor, produtor, **atores):
        for personagem in atores.keys():
            print "%s: %s" % (personagem, atores[personagem])
        print "-" * 20
        print "Diretor:  %s" % diretor
        print "Produtor: %s" % produtor

    >>> equipe(diretor="Paul Anderson", 
    ...        produtor="Paul Anderson", 
    ...        Frank="Tom Cruise", Edmund="Pat Healy", 
    ...        Linda="Julianne Moore")

    Frank: Tom Cruise
    Edmund: Pat Healy
    Linda: Julianne Moore
    --------------------
    Diretor: Paul Anderson
    Produtor: Paul Anderson

ou ainda as duas formas combinadas. Estes parâmetros especiais devem necessariamente ser os últimos definidos na lista de parâmetros da função. Note que estes argumentos especiais não agregam parâmetros que correspondem a argumentos explicitamente definidos, como alvo, diretor e produtor nos exemplos acima; estes são processados de maneira normal.

Conjuntos de argumentos opcionais são uma excelente forma de conferir flexibilidade a uma função mantendo compatibilidade com código pré-existente, sem prejudicar a sua legibilidade.

2.6.2.4 Escopo de variáveis

Embora o tema escopo seja complexo, e não esteja restrito apenas a funções, cabe aqui uma observação sobre o escopo das variáveis definidas no corpo de funções.

Tanto as variáveis definidas no corpo de uma função, como a variável i no exemplo abaixo, quanto os argumentos da função são acessíveis apenas no escopo local; em outras palavras, apenas no bloco de código da própria função.

    v = 0
    w = 1
    def verifica(a, b):
        i = 0
        # Neste bloco de código, v, w, a, b e i são acessíveis.

    def cancela(x, y):
        i = 0
        # Neste bloco de código, v, w, x, y e i são acessíveis, 
        # mas note que *este* i não tem nenhuma relação com
        # o i da função verifica() acima.

Variáveis definidas no corpo principal (ou seja, definidas em um bloco não-indentado, como as variáveis v e w acima) de um módulo podem ser lidas em qualquer função contida naquele arquivo; no entanto, não podem ser alteradas9.

Caso se deseje definir ou atribuir um novo valor a uma variável global, existe uma instrução especial, global. Esta instrução indica que a variável cujo nome for especificado é para ser definida no escopo global, e não local.

    v = 0
    def processa(t):
        global v
        v = 1

No código acima, a função altera o valor da variável global v.

Há duas funções úteis para estudar os escopos que se aplicam em um determinado contexto:

O escopo de variáveis funciona de maneira semelhante quando tratando com métodos e definições de classes, que serão discutidos na seção 4.



Notas de rodapé

... alteradas9
O motivo pelo qual existe esta distinção está intimamente associado à forma como Python atribui variáveis. Ao realizar uma operação de atribuição, a variável é sempre definida no escopo local; acesso à variável, no entanto, efetua uma busca nos escopos, do mais local para o mais global.