Fu

Funções em Python

{one: "1 exercício", many: "%{count} de exercícios", other: "%{count} exercícios"}

Sobre Funções

Uma function é um bloco de código organizado e reutilizável usado para realizar uma tarefa específica. As Functions oferecem melhor modularidade para sua aplicação e um alto grau de reutilização de código. O Python, como outras linguagens de programação, tem funções embutidas (print, map e assim por diante) que já estão prontas para usar. Você também pode definir suas próprias funções. Elas são chamadas de user-defined functions. As funções podem fazer algo tão simples quanto imprimir uma mensagem no console ou podem ser bastante complexas.

Para executar o código dentro de uma função, você precisa chamar a função, o que é feito usando o nome da função seguido de parênteses [()]. Dados, conhecidos como arguments, podem ser passados para a função colocando-os dentro dos parênteses. Uma definição de função pode incluir zero ou mais parameters. Os parâmetros definem quais argumentos a função aceita. Um parâmetro define qual tipo de argumento deve ser passado. O argumento é o valor real passado quando a função é chamada. As funções podem realizar tarefas diferentes dependendo dos argumentos passados aos parâmetros.

Uma função também pode retornar um valor usando a palavra-chave return. O valor retornado pela função é conhecido como return value. O valor de retorno é retornado para quem chamou a função.

Criação

No Python, as funções são criadas usando a palavra-chave def. A definição da função é seguida pelo nome da função e por parênteses [()]. Dentro dos parênteses, os parâmetros são especificados, separados por vírgulas. Depois do parêntese de fechamento, os dois-pontos (:) são usados para separar a assinatura da função do corpo da função.

O corpo da função é um bloco de código executado quando a função é chamada. O corpo da função é indentado. A indentação é importante porque o Python depende dela para saber onde aquele bloco de código termina. Um valor pode ser retornado da função usando a palavra-chave return, que pode então ser usado por quem chamou a função.

def function_name(parameter1, parameter2, ...):
    # function body
    return parameter1 + parameter2

Também podemos definir uma função sem parâmetros nem valor de retorno.

def function_name():
    # function body
    pass

Repare que a função precisa de um corpo, mesmo que o corpo não faça nada, ou tentar rodar o programa vai gerar um erro de indentação:

>>> def my_bodyless_func():
...      

File ~/temp.py:1
    
    ^
IndentationError: expected an indented block

Chamando uma função

Para chamar uma função, use o nome da função seguido de parênteses [()]. Os parâmetros passados para a função são colocados dentro dos parênteses, separados por vírgulas.

Considere a seguinte função:

def greet():
    print("Hello")

A função acima pode ser chamada usando a seguinte sintaxe:

>>> greet()
Hello

Parâmetros e seus argumentos

Argumentos são valores passados para a função quando ela é chamada. Eles podem ser de qualquer tipo de dado, incluindo outras funções ou classes.

Vamos definir uma função add que soma dois números:

def add(first, second):
    print(first + second)

Os parâmetros first e second definem quais argumentos a função add vai aceitar. (Vale notar que as palavras parameter e argument são frequentemente usadas de forma intercambiável, ainda que de modo impreciso.) Quando a função é chamada, os argumentos são passados para ela. Precisamos passar argumentos para os dois parâmetros, caso contrário um TypeError será lançado.

>>> add(2, 3)
5

# Function can be called multiple times, with different parameters
>>> add(4, 3)
7
>>> add(5, 6)
11

# Passing an incorrect number of parameters will raise a `TypeError`
>>> add(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'second'

>>> add(2, 3, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes 2 positional arguments but 3 were given

Valor de retorno

O valor de retorno é um valor que é retornado para quem chamou a função. Um return value pode ser qualquer tipo de dado, incluindo outras funções ou classes. Ele pode ser usado por quem chamou a função para realizar outras operações. Se uma função não define explicitamente um return value, o valor None será retornado pelo interpretador do Python.

Vamos definir uma função add:

def add(first, second):
    return first + second

Podemos guardar o valor de retorno em uma variável e depois imprimi-lo:

>>> result = add(2, 3)
>>> print(result)
5
# Type of result is `int`
>>> type(result)
<class 'int'>

# We can also perform operations on the return value
>>> result * 2
10

# A function without an explicit return value will return `None`
>>> def log(message):
    print(message)

# Hello is printed because of print(message), but return value is `None`
>>> return_value = log("Hello")
Hello
>>> return_value
None

O uso de return encerra a função imediatamente e retorna o valor para quem a chamou.

>>> def show(first, second):
    print(first)
    return first
    print(second)

# second never gets printed, because the function exits after the return statement
>>> show(1, 2)
1

Modularidade

Programas complexos podem ser divididos em partes menores. Funções diferentes podem ser usadas para realizar tarefas específicas diferentes.

Suponha que um programa precise realizar as seguintes tarefas:

  • Calcular a área de um círculo
  • Calcular a área de um retângulo
  • Calcular a área de um triângulo

Podemos dividir o programa em partes menores.

def circle_area(radius):
    return 3.14 * radius * radius

def rectangle_area(length, breadth):
    return length * breadth

def triangle_area(base, height):
    return 0.5 * base * height

Agora podemos chamar as funções na ordem que quisermos.

>>> circle_area(2)
12.56
>>> triangle_area(2, 3)
3.0
>>> rectangle_area(2, 3)
6
>>> rectangle_area(1, 2) + circle_area(2) + triangle_area(1, 2)
15.56

Escopo das variáveis

Se uma variável (ou nome) é definida dentro de uma função, ela só será acessível dentro do escopo da função (ou namespace local), mesmo que exista uma variável com o mesmo nome fora do escopo da função.

Variáveis definidas fora de uma função, no nível do módulo, são consideradas no namespace global. Variáveis definidas fora de uma função, mas dentro de uma função ou classe que a envolve, estão no namespace nonlocal.

O Python usa a Regra LEGB (Local, Enclosing, Global, Built-in) para resolver nomes de variáveis quando um programa está rodando:

  1. Busca no namespace local (ou da função).
  2. Busca no namespace enclosing (ou nonlocal) se um nome não for encontrado no local.
  3. Busca no namespace global (nível do módulo) se o nome não for encontrado no nonlocal/enclosing.
  4. Busca no namespace built-in (do programa ou de todo o Python) se o nome não for encontrado no global.

Se o nome continuar sem resolução, o Python vai lançar uma NameError exception.

# Global namespace.
general_favorite = "apples"


def alices_favorite():
   # Local namespace.  
   favorite = "cherries"
   
   # This works because Python will eventually find general_favorite in the global namespace.
   # Python will find 'print' in the built-in namespace.
   print(f'Alice has always liked {favorite}, but most people like {general_favorite}.')

   
def our_favorite_fruits():
    # Enclosing or nonlocal namespace.
    yours = "peaches"
    
    def my_favorite():
        # Local namespace.
        mine = "pears"
        
        # This works because Python will eventually find 'yours' in the enclosing/nonlocal namespace.
        print(f'My favorite is {mine}, but you like {yours} instead.')
        
        # This works because Python will eventually find 'general_favorite' in the global namespace.
        print(f'Everyone seems to like {general_favorite}')
    
    # This function is in the local namespace of the 'our_favorite_fruits' function.  
    my_favorite()

    
# This will raise NameError: name 'favorite' is not defined, because the variable favorite is local to alices_favorite.
print(favorite)

Se quisermos tornar um nome de variável acessível fora do escopo local da função (ou modificar uma variável que foi definida fora do escopo da função), precisamos usar as palavras-chave global ou nonlocal.

Usar a palavra-chave global sinaliza ao Python para começar a busca no namespace global. As atribuições à variável vão então modificar a variável global, em vez de criar uma versão local. Quando global é usado para declarar uma variável, a variável será adicionada ao namespace global. Por isso, global deve ser usado com cautela, já que adicionar ou modificar uma variável global pode afetar todo o restante do código que usa o valor dela.

A palavra-chave nonlocal sinaliza ao Python para procurar/criar a variável no namespace nonlocal ou enclosing. Ela é usada quando uma função está aninhada dentro de outra função ou classe e precisa acessar as variáveis e o escopo da função externa.

Funções como objetos de primeira classe

No Python, funções podem ser atribuídas a variáveis e passadas como argumentos para outras funções. Elas podem ser usadas como valores de retorno. Funções também podem ser colocadas em uma sequência (list, tuple etc.) ou como valor em um dict. Funções podem ser usadas em qualquer lugar onde qualquer outro objeto pode ser usado. Isso acontece porque funções são objetos de primeira classe. Como tal, elas carregam atributos especiais e podem até definir obtenção e atribuição de atributos personalizados próprios.

# print is a function

# A function can be assigned to a variable.
>>> function_as_variable = print
>>> function_as_variable("Hello")
Hello
>>> type(fake_print)
<class 'builtin_function_or_method'>

# Functions can be passed as an argument to another function.
>>> def check_print(func):
    func("Hello")
>>> check_print(print)
Hello

# Function can be used as an item in a sequence.
>>> my_list = [print, "Hello"]
>>> my_list[0]("Hello")
Hello

# Functions can be used as a value in a dictionary.
>>> my_dict = {"key": print}
>>> my_dict["key"]("Hello")
Hello

# Functions can be returned from a function.
>>> def return_func():
    return print
>>> return_func()("Hello")
Hello

Funções também podem ser aninhadas dentro de outras funções.

def outer():
    num = 10
    
    # This is a nested, or "inner" function.
    def inner():
        print(num)
    
    # Outer function calling inner function
    inner()

A função interna pode acessar a variável num definida na função externa.

>>> outer()
10

Atributos especiais

As funções no Python têm atributos especiais. Alguns deles são:

  • __name__: Nome da função
  • __doc__: String de documentação da função
  • __module__: Módulo no qual a função é definida
  • __globals__: Dicionário de variáveis globais da função
  • __code__: Objeto de código que contém as instruções da função
>>> def add(first, second):
      return first + second

# Function name
>>> print.__name__
'print'
>>> len.__name__
'len'
>>> add.__name__
'add'

# Function documentation
>>> abs.__doc__
'Return the absolute value of the argument.'

# Module
>>> len.__module__
'builtins'
>>> add.__module__
'__main__'

A lista completa dos atributos de função pode ser encontrada em Python DataModel.

Editar via GitHub O link abre em uma nova janela ou aba