Uma function é um bloco de código organizado e reutilizável que serve para realizar uma tarefa específica.
Functions proporcionam uma melhor modularidade à tua aplicação e um elevado grau de reutilização de código.
O Python, tal como outras linguagens de programação, tem funções incorporadas (print, map, etc.) que estão disponíveis de imediato.
Também podes definir as tuas próprias funções. Essas chamam-se user-defined functions.
As funções podem fazer algo tão simples como imprimir uma mensagem na consola ou podem ser bastante complexas.
Para executar o código dentro de uma função, tens de chamar a função, o que se faz usando o nome da função seguido de parênteses [()].
Os dados, conhecidos como arguments, podem ser passados à função colocando-os dentro dos parênteses.
A definição de uma função pode incluir zero ou mais parameters.
Os parâmetros definem que argumentos a função aceita.
Um parâmetro define que tipo de argumento deve ser passado.
O argumento é o valor concreto passado quando a função é chamada.
As funções podem realizar tarefas diferentes consoante os argumentos passados aos parâmetros.
Uma função também pode devolver um valor usando a palavra-chave return.
O valor devolvido pela função é conhecido como return value.
O valor devolvido é entregue a quem chamou a função.
Em Python, as funções criam-se com a palavra-chave def.
A definição da função é seguida pelo nome da função e por parênteses [()].
Dentro dos parênteses indicam-se os parâmetros, separados por vírgulas.
Depois do parêntese de fecho, os dois pontos (:) separam a assinatura da função do corpo da função.
O corpo da função é um bloco de código que é executado quando a função é chamada.
O corpo da função está indentado.
A indentação é importante porque o Python baseia-se nela para saber onde termina esse bloco de código.
Podes devolver um valor da função com a palavra-chave return, que pode depois 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 e sem valor devolvido.
def function_name():
# function body
pass
Repara que a função precisa de um corpo, mesmo que o corpo não faça nada, caso contrário tentar executar o programa vai gerar um erro de indentação:
>>> def my_bodyless_func():
...
File ~/temp.py:1
^
IndentationError: expected an indented block
Para chamar uma função, usa o nome da função seguido de parênteses [()].
Os parâmetros passados à função são colocados dentro dos parênteses, separados por vírgulas.
Considera a seguinte função:
def greet():
print("Hello")
A função acima pode ser chamada com a seguinte sintaxe:
>>> greet()
Hello
Os argumentos são valores que são passados à função quando esta é chamada. Podem ser de qualquer tipo de dados, 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 que argumentos a função add vai aceitar.
(Convém notar que as palavras parameter e argument são usadas muitas vezes como sinónimos, ainda que de forma imprecisa.)
Quando a função é chamada, os argumentos são passados à função.
É preciso passar argumentos para os dois parâmetros, caso contrário será lançado um TypeError.
>>> 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
O valor devolvido é o valor que é entregue a quem chamou a função.
Um return value pode ser de qualquer tipo de dados, incluindo outras funções ou classes.
Pode ser usado por quem chamou a função para realizar mais operações.
Se uma função não definir explicitamente um return value, o intérprete de Python vai devolver o valor None.
Vamos definir uma função add:
def add(first, second):
return first + second
Podemos guardar o valor devolvido numa 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 faz a função terminar de imediato e devolve o valor a 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
Os programas complexos podem ser divididos em partes mais pequenas. Podem usar-se funções diferentes para realizar tarefas específicas diferentes.
Imagina que um programa tem de realizar as seguintes tarefas:
Podemos dividir o programa em partes mais pequenas.
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 pela 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
Se uma variável (ou um nome) for definida dentro de uma função, só vai ser acessível dentro do âmbito da função (ou espaço de nomes local), mesmo que exista uma variável com o mesmo nome fora do âmbito da função.
As variáveis definidas fora de uma função, ao nível do módulo, consideram-se no espaço de nomes global. As variáveis definidas fora de uma função mas dentro de uma função ou classe que a envolve estão no espaço de nomes nonlocal.
O Python usa a LEGB Rule (Local, Enclosing, Global, Built-in) para resolver nomes de variáveis enquanto um programa está a correr:
Se o nome continuar por resolver, 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 âmbito local da função (ou modificar uma variável definida fora do âmbito da função), temos de usar as palavras-chave global ou nonlocal.
Usar a palavra-chave global indica ao Python para começar a procura no espaço de nomes global.
As atribuições à variável passam então a modificar a variável global, em vez de criar uma versão local.
Quando global é usado para declarar uma variável, a variável é adicionada ao espaço de nomes global.
Por isso, global deve ser usado com cautela, já que adicionar ou modificar uma variável global pode ter efeitos em todo o restante código que usa o seu valor.
A palavra-chave nonlocal indica ao Python para procurar/criar a variável no espaço de nomes nonlocal ou envolvente.
Usa-se quando uma função está aninhada dentro de outra função ou classe e precisa de aceder às variáveis e ao âmbito da função exterior.
Em Python, as funções podem ser atribuídas a variáveis e passadas como argumentos a outras funções.
Podem ser usadas como valores devolvidos.
As funções também podem ser colocadas numa sequência (list, tuple, etc.) ou como valor num dict.
As funções podem ser usadas em qualquer sítio onde se possa usar outro objeto.
Isto acontece porque as funções são objetos de primeira classe.
Por isso, têm atributos especiais e podem até definir a leitura e a escrita dos seus próprios atributos personalizados.
# 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
As funções também podem estar 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 interior pode aceder à variável num definida na função exterior.
>>> outer()
10
As funções em Python têm atributos especiais. Alguns deles são:
__name__: o nome da função__doc__: a string de documentação da função__module__: o módulo em que a função está definida__globals__: dicionário de variáveis globais da função__code__: o 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 de atributos das funções pode ser consultada em Python DataModel.