Introdução
Neste laboratório, você aprenderá como definir e usar funções Python. Começaremos com exemplos simples e aumentaremos gradualmente a complexidade.
Vamos começar!
Conquistas
- Funções Python
Neste laboratório, você aprenderá como definir e usar funções Python. Começaremos com exemplos simples e aumentaremos gradualmente a complexidade.
Vamos começar!
Para definir uma função Python, você precisa usar a palavra-chave def seguida pelo nome da função e um conjunto de parênteses que podem conter argumentos. O corpo da função é indentado e segue o caractere :.
Abra um novo interpretador Python.
python3
Aqui está um exemplo de uma função simples que recebe um único argumento x e retorna o quadrado de x:
def square(x):
return x ** 2
Neste exemplo, a função square recebe um único argumento x e retorna o quadrado de x. O valor é retornado ao chamador usando a instrução return.
Para chamar uma função, basta usar o nome da função seguido por um conjunto de parênteses e quaisquer argumentos necessários. Por exemplo:
result = square(5) ## result is 25
print(result)
Se uma função não tiver uma instrução return, ela retornará None por padrão. Por exemplo:
def square(x):
print(x ** 2)
result = square(5) ## result is None
print(result)
Você deve saber a diferença entre as instruções return e print. A instrução print é usada para imprimir o valor na tela, mas a instrução return é usada para retornar o valor da função.
Também é possível usar a instrução return para encerrar a execução de uma função antecipadamente. Por exemplo:
def find_first_positive(numbers):
for number in numbers:
if number > 0:
return number
return None
result = find_first_positive([-1, -2, 3, -4, 5]) ## result is 3
print(result)
Neste exemplo, a função find_first_positive retorna o primeiro número positivo na lista numbers, ou None se nenhum número positivo for encontrado. A instrução return encerra a execução da função assim que um número positivo é encontrado.
Às vezes, é útil especificar valores padrão para argumentos de função. Dessa forma, a função pode ser chamada sem passar um valor para esse argumento, e o valor padrão será usado em vez disso.
Aqui está um exemplo de uma função que calcula a área de um retângulo. Ela recebe dois argumentos: o comprimento e a largura do retângulo. Podemos especificar valores padrão para ambos os argumentos, de modo que a função possa ser chamada com apenas um argumento se o comprimento e a largura forem iguais:
def rectangle_area(length, width=1):
return length * width
print(rectangle_area(5)) ## Output: 5
print(rectangle_area(5, 2)) ## Output: 10
Neste exemplo, o argumento width tem um valor padrão de 1. Se a função for chamada com apenas um argumento, o valor padrão de 1 é usado para a width.
Experimente você mesmo: defina uma função chamada power que recebe dois argumentos: uma base x e um expoente n. Torne o argumento do expoente opcional, com um valor padrão de 2. Em seguida, chame a função com valores diferentes para a base e o expoente.
def power(x, n=2):
return x ** n
print(power(2)) ## Output: 4
print(power(2, 3)) ## Output: 8
Em Python, as dicas de tipo de argumento de função indicam o tipo esperado de um argumento passado para uma função. Elas foram introduzidas no Python 3.5 e são denotadas por dois pontos seguidos pelo tipo, colocados após o nome do argumento na definição da função.
As dicas de tipo são opcionais e não afetam o comportamento em tempo de execução do código. Elas são usadas principalmente por ferramentas como IDEs e Linters para fornecer melhor análise de código e sugestões de preenchimento automático.
Por exemplo, considere a seguinte função que recebe dois argumentos, um inteiro e uma string, e retorna sua concatenação:
def concatenate(a: int, b: str) -> str:
return str(a) + b
print(concatenate(1, "world")) ## "1world"
Neste exemplo, as dicas de tipo int e str indicam que o primeiro argumento a deve ser um inteiro e o segundo argumento b deve ser uma string.
As dicas de tipo também podem ser usadas com classes e suas instâncias, por exemplo:
class MyClass:
pass
def my_function(a: MyClass) -> None:
pass
Vale a pena mencionar que as dicas de tipo são opcionais e não afetam o comportamento em tempo de execução do código. Elas são usadas principalmente por ferramentas como IDEs e Linters para fornecer melhor análise de código e sugestões de preenchimento automático.
Além disso, o Python tem um módulo chamado typing que contém tipos úteis como List, Tuple, Dict, Set, etc., que podem ser usados para dar dicas sobre os tipos de elementos em uma coleção.
from typing import List, Tuple
def my_function(a: List[int], b: Tuple[str, int]) -> None:
pass
É uma boa prática usar dicas de tipo em seu código para torná-lo mais legível e fácil de manter.
Uma docstring é uma literal de string que ocorre como a primeira instrução em um módulo, função, classe ou definição de método. Tal docstring se torna o atributo especial __doc__ desse objeto.
Docstrings são usadas para documentar o código e são escritas em texto simples. Elas são delimitadas por aspas triplas """ e geralmente são colocadas no início da definição da função.
def my_function():
"""This is a docstring."""
pass
Docstrings geralmente contêm uma breve descrição da função, seus argumentos e seu valor de retorno. Elas também podem conter uma descrição mais longa do comportamento da função.
def my_function(a: int, b: int) -> int:
"""Return the sum of a and b.
Args:
a (int): The first number.
b (int): The second number.
Returns:
int: The sum of a and b.
"""
return a + b
Em Python, uma função pode retornar múltiplos valores usando uma tupla. Aqui está um exemplo de uma função que calcula os valores mínimo e máximo de uma lista:
def min_max(numbers):
return min(numbers), max(numbers)
nums = [1, 2, 3, 4, 5]
min_val, max_val = min_max(nums)
print("Minimum value:", min_val) ## Output: "Minimum value: 1"
print("Maximum value:", max_val) ## Output: "Maximum value: 5"
Neste exemplo, a função min_max retorna uma tupla contendo os valores mínimo e máximo da lista numbers. A tupla é desempacotada nas variáveis min_val e max_val quando a função é chamada.
Aqui está outro exemplo de retorno de múltiplos valores de uma função:
def get_student_info(name):
if name == "John":
return "John", "Doe", "Computer Science"
elif name == "Jane":
return "Jane", "Smith", "Physics"
else:
return "Unknown", "Unknown", "Unknown"
first_name, last_name, major = get_student_info("John")
print("First name:", first_name) ## Output: "First name: John"
print("Last name:", last_name) ## Output: "Last name: Doe"
print("Major:", major) ## Output: "Major: Computer Science"
first_name, last_name, major = get_student_info("Jane")
print("First name:", first_name) ## Output: "First name: Jane"
print("Last name:", last_name) ## Output: "Last name: Smith"
print("Major:", major) ## Output: "Major: Physics"
first_name, last_name, major = get_student_info("Bob")
print("First name:", first_name) ## Output: "First name: Unknown"
print("Last name:", last_name) ## Output: "Last name: Unknown"
print("Major:", major) ## Output: "Major: Unknown"
Neste exemplo, a função get_student_info recebe o nome de um aluno e retorna uma tupla contendo o primeiro nome, o sobrenome e o curso do aluno. A tupla é desempacotada em variáveis separadas quando a função é chamada.
Se o nome do aluno não for reconhecido, a função retorna uma tupla com valores "Unknown".
Em Python, você pode especificar argumentos de função usando "argumentos de palavra-chave" (keyword arguments). Quando você usa argumentos de palavra-chave, você especifica o nome do argumento seguido pelo valor, e os argumentos podem ser fornecidos em qualquer ordem.
Aqui está um exemplo de uma função que recebe dois argumentos: um nome e uma mensagem:
def greet(name, message):
print("Hello, " + name + "! " + message)
greet(message="How are you?", name="John") ## Output: "Hello, John! How are you?"
Neste exemplo, a função greet é chamada com os argumentos "John" e "How are you?", mas os argumentos são fornecidos em uma ordem diferente daquela em que são definidos na função. Ao usar argumentos de palavra-chave, você pode especificar os argumentos em qualquer ordem e tornar o código mais legível.
Você também pode misturar argumentos de palavra-chave com argumentos posicionais, desde que os argumentos posicionais sejam fornecidos primeiro. Por exemplo:
def greet(name, message):
print("Hello, " + name + "! " + message)
greet("John", message="How are you?") ## Output: "Hello, John! How are you?"
Neste exemplo, o argumento name é fornecido como um argumento posicional, enquanto o argumento message é fornecido como um argumento de palavra-chave.
Argumentos de palavra-chave são especialmente úteis quando uma função tem um grande número de argumentos, ou quando os argumentos têm valores padrão. Por exemplo:
def create_user(name, age=18, gender="unknown"):
print("Creating user:", name, age, gender)
create_user("John") ## Output: "Creating user: John 18 unknown"
create_user("Jane", gender="female") ## Output: "Creating user: Jane 18 female"
create_user("Bob", 25, "male") ## Output: "Creating user: Bob 25 male"
Neste exemplo, a função create_user recebe três argumentos: name, age e gender. Os argumentos age e gender têm valores padrão, então eles são opcionais. Ao usar argumentos de palavra-chave, você pode especificar apenas os argumentos que deseja fornecer, e os valores padrão serão usados para o restante.
Em Python, você pode usar a sintaxe *args e **kwargs para definir uma função que pode receber um número variável de argumentos.
A sintaxe *args é usada para passar um número variável de argumentos não nomeados (non-keyworded) para uma função. Por exemplo:
def print_numbers(*args):
for arg in args:
print(arg)
print_numbers(1, 2, 3, 4, 5) ## Output: 1, 2, 3, 4, 5
print_numbers(10, 20, 30) ## Output: 10, 20, 30
Neste exemplo, a função print_numbers recebe um número variável de argumentos e os imprime no console. A sintaxe *args é usada para definir a função, e os argumentos são passados como uma tupla para a função.
A sintaxe **kwargs é usada para passar um número variável de argumentos nomeados (keyworded) para uma função. Por exemplo:
def print_keywords(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
print_keywords(name="John", age=30, city="New York")
## Output:
## name : John
## age : 30
## city : New York
print_keywords(country="USA", population=327000000)
## Output:
## country : USA
## population : 327000000
Neste exemplo, a função print_keywords recebe um número variável de argumentos nomeados e os imprime no console. A sintaxe **kwargs é usada para definir a função, e os argumentos são passados como um dicionário para a função.
Você pode misturar a sintaxe *args e **kwargs com outros argumentos em uma definição de função, desde que os argumentos *args e **kwargs sejam fornecidos por último. Por exemplo:
def print_info(title, *args, **kwargs):
print(title)
for arg in args:
print(arg)
for key, value in kwargs.items():
print(key, ":", value)
print_info("Person", "John", "Jane", "Bob", age=30, city="New York")
## Output:
## Person
## John
## Jane
## Bob
## age : 30
## city : New York
Neste exemplo, a função print_info recebe um argumento fixo title, seguido por um número variável de argumentos não nomeados (*args) e um número variável de argumentos nomeados (**kwargs). Os argumentos são passados para a função na ordem em que são definidos: primeiro o título, depois *args e, finalmente, **kwargs.
A sintaxe *args e **kwargs pode ser útil quando você deseja definir uma função flexível que pode aceitar um número variável de argumentos. Elas também podem tornar o código mais legível, permitindo que você evite o uso de nomes de argumentos codificados (hard-coded) na definição da função.
Aqui está um exemplo de uma função que usa *args e **kwargs para criar um dicionário de argumentos:
def create_dict(**kwargs):
return kwargs
my_dict = create_dict(name="John", age=30, city="New York")
print(my_dict) ## Output: {'name': 'John', 'age': 30, 'city': 'New York'}
my_dict = create_dict(a=1, b=2, c=3)
print(my_dict) ## Output: {'a': 1, 'b': 2, 'c': 3}
Neste exemplo, a função create_dict recebe um número variável de argumentos nomeados e os retorna como um dicionário. A sintaxe **kwargs é usada para definir a função, e os argumentos são passados como um dicionário para a função.
Você também pode usar o operador * para "desempacotar" (unpack) uma lista ou tupla em argumentos separados ao chamar uma função. Por exemplo:
def print_numbers(*args):
for arg in args:
print(arg)
numbers = [1, 2, 3, 4, 5]
print_numbers(*numbers) ## Output: 1, 2, 3, 4, 5
tuple_of_numbers = (10, 20, 30)
print_numbers(*tuple_of_numbers) ## Output: 10, 20, 30
Neste exemplo, o operador * é usado para desempacotar a lista numbers e a tupla tuple_of_numbers em argumentos separados ao chamar a função print_numbers.
Você também pode usar o operador ** para "desempacotar" (unpack) um dicionário em argumentos nomeados ao chamar uma função. Por exemplo:
def print_keywords(**kwargs):
for key, value in kwargs.items():
print(key, ":", value)
my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
print_keywords(**my_dict)
## Output:
## name : John
## age : 30
## city : New York
another_dict = {'country': 'USA', 'population': 327000000}
print_keywords(**another_dict)
## Output:
## country : USA
## population : 327000000
Neste exemplo, o operador ** é usado para desempacotar os dicionários my_dict e another_dict em argumentos nomeados ao chamar a função print_keywords.
Em Python, você pode usar "funções lambda" para criar funções anônimas. Funções lambda são funções pequenas que não têm um nome e geralmente são definidas e chamadas em uma única linha de código.
Aqui está um exemplo de uma função lambda que recebe dois argumentos e retorna sua soma:
sum = lambda x, y: x + y
result = sum(1, 2) ## result is 3
Neste exemplo, a palavra-chave lambda é usada para definir uma função lambda que recebe dois argumentos x e y e retorna sua sum. A função lambda é atribuída à variável sum e pode ser chamada como qualquer outra função.
Você pode usar uma função normal em vez de uma função lambda para definir a mesma função?
def sum(x, y):
return x + y
result = sum(1, 2) ## result is 3
Funções lambda são frequentemente usadas como um atalho para definir funções simples. Elas são especialmente úteis quando você deseja passar uma função como um argumento para outra função, ou quando você deseja definir uma função inline.
Aqui está um exemplo de como usar uma função lambda como um argumento para a função sorted:
words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words) ## Output: ['apple', 'date', 'banana', 'cherry']
Neste exemplo, a função sorted recebe uma lista de palavras e uma função "key" (chave) que especifica como as palavras devem ser ordenadas. A função lambda passada como a função chave retorna o comprimento de cada palavra, e as palavras são ordenadas com base em seu comprimento.
Aqui está um exemplo de como definir uma função lambda inline:
result = (lambda x: x ** 2)(5) ## result is 25
Neste exemplo, a função lambda recebe um único argumento x e retorna o quadrado de x. A função lambda é definida e chamada em uma única linha de código, e o result é atribuído à variável result.
Funções lambda são frequentemente usadas em Python para funções curtas e simples que não precisam ser reutilizadas em outras partes do código. Elas são uma maneira conveniente de definir pequenas funções "on the fly" (na hora), sem a necessidade de definir uma função separada usando a palavra-chave def.
Em Python, as variáveis definidas dentro de uma função são "locais" para a função e estão disponíveis apenas dentro da função. Variáveis definidas fora de uma função são "globais" e estão disponíveis em todo o programa.
Aqui está um exemplo de uma variável global:
message = "Hello, world!"
def greet():
print(message)
greet() ## Output: "Hello, world!"
Neste exemplo, a variável message é definida fora da função greet, portanto, é uma variável global. A função greet pode acessar e imprimir a variável message, porque ela está disponível em todo o programa.
Aqui está um exemplo de uma variável local:
def greet(name):
message = "Hello, " + name + "!"
print(message)
greet("John") ## Output: "Hello, John!"
print(message) ## Output: NameError: name 'message' is not defined
Neste exemplo, a variável message é definida dentro da função greet, portanto, é uma variável local. A função greet pode acessar e imprimir a variável message, mas ela não está disponível fora da função. Se você tentar acessar a variável message fora da função, você receberá um NameError porque a variável não está definida.
Você também pode usar a palavra-chave global para modificar uma variável global dentro de uma função. Por exemplo:
message = "Hello, world!"
def greet():
global message
message = "Hello, Python!"
print(message)
greet() ## Output: "Hello, Python!"
print(message) ## Output: "Hello, Python!"
Neste exemplo, a função greet usa a palavra-chave global para modificar a variável global message. A função greet imprime o valor modificado de message, e o valor de message também é modificado fora da função.
Geralmente, é uma boa ideia evitar o uso de variáveis global, porque elas podem tornar o código mais difícil de entender e manter. É geralmente melhor passar variáveis para funções como argumentos e retorná-las como resultados, em vez de modificar variáveis global.
Em Python, você pode passar uma função como um argumento para outra função. Isso é chamado de "função de ordem superior" (higher-order function). Aqui está um exemplo de uma função que recebe outra função como argumento e a chama várias vezes:
def greet(name):
print("Hello, " + name + "!")
def call(func, args):
for arg in args:
func(arg)
names = ["John", "Jane", "Bob"]
call(greet, names) ## Output: "Hello, John!", "Hello, Jane!", "Hello, Bob!"
Neste exemplo, a função call recebe dois argumentos: uma função func e uma lista de argumentos args. Ela chama a função func com cada elemento da lista args como um argumento.
Tente você mesmo: defina uma função chamada apply que recebe uma função e uma lista de números e retorna uma nova lista contendo o resultado da aplicação da função a cada elemento da lista.
def square(x):
return x ** 2
def apply(func, numbers):
result = []
for number in numbers:
result.append(func(number))
return result
numbers = [1, 2, 3, 4, 5]
squared_numbers = apply(square, numbers)
print(squared_numbers) ## Output: [1, 4, 9, 16, 25]
Este passo pode ser um pouco difícil, não se preocupe se você não conseguir resolvê-lo. Você pode pular e voltar a ele mais tarde.
Agora você deve ter uma boa compreensão de como trabalhar com funções Python. Aqui estão alguns dos pontos-chave:
def, seguida pelo nome da função e argumentos.return para retornar um valor da função.*args para definir uma função que pode receber um número variável de argumentos não nomeados (non-keyworded arguments), e a sintaxe **kwargs para definir uma função que pode receber um número variável de argumentos nomeados (keyworded arguments).lambda para criar funções anônimas que são definidas e chamadas em uma única linha de código.