Introdução À Linguagem Python - Unidade 1 Seção 5
Introdução À Linguagem Python - Unidade 1 Seção 5
Introdução À Linguagem Python - Unidade 1 Seção 5
FUNÇÕES EM PYTHON
Vanessa Cadan Scheffer
Fonte: Shutterstock.
O assunto desta seção será funções. Por que precisamos aprender essa técnica de programação?
Segundo Banin (2018, p. 119), "... funções constituem um elemento de fundamental importância na
moderna programação de computadores, a ponto de ser possível afirmar que atualmente nenhum
programa de computador é desenvolvido sem o uso desse recurso".
Para entendermos, com clareza, o que é uma função, vamos pensar na organização de um escritório
de advocacia. Nesse escritório, existe um secretário que possui a função de receber os clientes e
agendar horários. Também trabalham nesse escritório três advogados, que possuem a função de
orientar e representar seus clientes com base nas leis. Não podemos deixar de mencionar os
colaboradores que possuem a função de limpar o escritório e fazer reparos. Mas o que o escritório
tem a ver com nossas funções? Tudo! Citamos algumas funções que podem ser encontradas nesse
ambiente de trabalho, ou seja, um conjunto de tarefas/ações associada a um "nome". Podemos,
então, resumir que uma função é uma forma de organização, usada para delimitar ou determinar
quais tarefas podem ser realizadas por uma determinada divisão.
memoryview(
abs() delattr() hash() set()
)
Fonte: https://docs.python.org/3/library/functions.html
Ao longo da disciplina, iremos conhecer várias outras, mas certamente vale a pena você acessar a
documentação https://docs.python.org/3/library/functions.html e explorar tais funções, aumentando
cada vez mais seu repertório. Para mostrar o poder das funções e deixar um gostinho de quero mais,
veja o código a seguir, com a utilização da função eval().
In [1]:
a = 2
b = 1
for x in range(5):
y = eval(equacao)
print(f"\nResultado da equação para x = {x} é {y}")
Digite a fórmual geral da equação linear (a * x + b): a * x + b
A função eval() foi mostrada a fim de exemplificar a variedade de funcionalidades que as funções
built-in possuem. Entretanto, precisamos ressaltar que eval é uma instrução que requer prudência
para o uso, pois é fácil alguém externo à aplicação fazer uma "injection" de código intruso.
Utilize o emulador a seguir, para testar o código e experimentar novas funções built-in em Python.
Vamos começar a desenvolver nossas funções, entendendo a sintaxe de uma função em Python.
Observe o código a seguir.
In [2]:
def nome_funcao():
# bloco de comandos
Veja que na linha 1 da entrada 2 (In [2]), usamos o comando "def" para indicar que vamos definir
uma função. Em seguida, escolhemos o nome da função "imprimir_mensagem", veja que não
possui acento, nem espaço, conforme recomenda a PEP 8 https://www.python.org/dev/peps/pep-
0008/#function-and-variable-names: os nomes das funções devem estar em minúsculas, com as
palavras separadas por underline, conforme necessário, para melhorar a legibilidade. Os nomes de
variáveis seguem a mesma convenção que os nomes de funções. Nomes com mixedCase (mistura
de maiúsculas e minúsculas) são permitidos apenas em contextos em que o nome já existe com o
formato recomendado.
Em toda declaração de função, após especificar o nome, é preciso abrir e fechar parênteses, pois é
dentro dos parênteses que os parâmetros de entrada da função devem ser definidos. Nessa versão da
nossa função "imprimir_mensagem", não existe nenhum parâmetro sendo passado como entrada. A
linha 2 representa o conjunto de ações que essa função deve executar, no caso, somente imprimir
uma mensagem na tela. Para que uma função execute suas ações, ela precisa ser "invocada",
fazemos isso na linha 5, colocando o nome da função, acompanhada dos parênteses.
Agora vamos criar uma segunda versão da nossa função "imprimir_mensagem". Observe o código a
seguir:
In [3]:
def imprimir_mensagem(disciplina, curso):
print(f"Minha primeira função em Python desenvolvida na disciplina:
{disciplina}, do curso: {curso}.")
imprimir_mensagem("Python", "ADS")
Minha primeira função em Python desenvolvida na disciplina: Python, do
curso: ADS.
Veja na linha 1 da entrada 3 (In [3]), que agora a função recebe dois parâmetros. Esses parâmetros
são variáveis locais, ou seja, são variáveis que existem somente dentro da função. Na linha 2,
imprimimos uma mensagem usando as variáveis passadas como parâmetro e na linha 5, invocamos
a função, passando como parâmetros dois valores do tipo string. O valor "Python" vai para o
primeiro parâmetro da função e o valor "ADS" vai para o segundo parâmetro.
In [4]:
def imprimir_mensagem(disciplina, curso):
print(f"Minha primeira função em Python desenvolvida na disciplina:
{disciplina}, do curso: {curso}.")
In [5]:
def imprimir_mensagem(disciplina, curso):
return f"Minha primeira função em Python desenvolvida na disciplina:
{disciplina}, do curso: {curso}."
In [6]:
def converter_mes_para_extenso(data):
mes = '''janeiro fevereiro março
abril maio junho julho agosto
setembro outubro novembro
dezembro'''.split()
d, m, a = data.split('/')
mes_extenso = mes[int(m) - 1] # O mês 1, estará na posição 0!
return f'{d} de {mes_extenso} de {a}'
print(converter_mes_para_extenso('10/05/2021'))
10 de maio de 2021
No grupo 1, temos os parâmetros que vão depender da ordem em que forem passados, por isso são
chamados de posicionais (a posição influencia o resultado). Os parâmetros desse grupo são
obrigatórios, ou seja, tentar um invocar a função, sem passar os parâmetros, acarreta um erro. Além
disso, os parâmetros não possuem valor default. Observe a função "somar" a seguir.
In [7]:
def somar(a, b):
return a + b
r = somar(2)
print(r)
-------------------------------------------------------------------------
--
TypeError Traceback (most recent call
last)
<ipython-input-7-4456bbb97a27> in <module>
2 return a + b
3
----> 4 r = somar(2)
5 print(r)
No grupo 2, também temos os parâmetros posicionais e obrigatórios, porém vamos definir um valor
default (padrão), assim, quando a função for invocada, caso nenhum valor seja passado, o valor
default é utilizado. Observe a função "calcular_desconto" a seguir.
In [8]:
def calcular_desconto(valor, desconto=0): # O parâmetro desconto possui
zero valor default
valor_com_desconto = valor - (valor * desconto)
return valor_com_desconto
A obrigatoriedade do argumento, quando não atendida, pode resultar em um erro, conforme vimos
na entrada 7 (In [7]). Porém, para o conceito de parâmetros posicionais não existe nenhum erro de
interpretação associado, ou seja, o interpretador não irá informar o erro, mas pode haver um erro de
lógica. Observe o código a seguir:
In [9]:
def cadastrar_pessoa(nome, idade, cidade):
print("\nDados a serem cadastrados:")
print(f"Nome: {nome}")
print(f"Idade: {idade}")
print(f"Cidade: {cidade}")
Com o exemplo da função "cadastrar_pessoa", fica claro como a posição dos argumentos, na hora
de chamar a função, deve ser conhecida e respeitada, pois a passagem dos valores na posição
incorreta pode acarretar erros lógicos.
O grupo de parâmetros 3 é caracterizado por ter parâmetros nominais, ou seja, agora não mais
importa a posição dos parâmetros, pois eles serão identificados pelo nome, os parâmetros são
obrigatórios, ou seja, na chamada da função é obrigatório passar todos os valores e sem valor
default (padrão). Observe a função "converter_maiuscula".
In [10]:
def converter_maiuscula(texto, flag_maiuscula):
if flag_maiuscula:
return texto.upper()
else:
return texto.lower()
O grupo de funções da categoria 4 é similar ao grupo 3: parâmetro nominal, obrigatório, mas nesse
grupo os parâmetros podem possuir valor default (padrão). Observe a função
"converter_minuscula" a seguir.
In [11]:
def converter_minuscula(texto, flag_minuscula=True): # O parâmetro
flag_minuscula possui True como valor default
if flag_minuscula:
return texto.lower()
else:
return texto.upper()
print(f"\nTexto 1 = {texto1}")
print(f"\nTexto 2 = {texto2}")
Texto 1 = linguagem de programação
Até o momento, para todas as funções que criamos, sabemos exatamente o número de parâmetros
que ela recebe. Mas existem casos em que esses parâmetros podem ser arbitráios, ou seja, a função
poderá receber um número diferente de parâmetros a cada invocação. Esse cenário é o que
carateriza os grupos 5 e 6 de funções que vamos estudar.
In [12]:
def imprimir_parametros(*args):
qtde_parametros = len(args)
print(f"Quantidade de parâmetros = {qtde_parametros}")
print("\nChamada 1")
imprimir_parametros("São Paulo", 10, 23.78, "João")
print("\nChamada 2")
imprimir_parametros(10, "São Paulo")
Chamada 1
Quantidade de parâmetros = 4
Posição = 0, valor = São Paulo
Posição = 1, valor = 10
Posição = 2, valor = 23.78
Posição = 3, valor = João
Chamada 2
Quantidade de parâmetros = 2
Posição = 0, valor = 10
Posição = 1, valor = São Paulo
A função "imprimir_parametros" na entrada 12 (In [12]) foi definida de modo a obter parâmetros
arbitrários. Tal construção é feita, passando como parâmetro o *args. O parâmetro não precisa ser
chamado de args, mas é uma boa prática. Já o asterisco antes do parâmetro é obrigatório. Na linha 2,
usamos a função built-in len() (length) para saber a quantidade de parâmetros que foram passados.
Como se trata de parâmetros posicionais não definidos, conseguimos acessar a posição e o valor do
argumento, usando a estrutura de repetição for e a função enumerate(). Agora observe as chamadas
feitas nas linhas 10 e 13, cada uma com uma quantidade diferente de argumentos, mas veja na saída
que os argumentos seguem a ordem posicional, ou seja, o primeiro vai para a posição 0, o segundo
para a 1 e assim por diante.
A seguir você pode testar o passo a passo de execução do código. Clique em "next" para visualizar
a execução de cada linha de código.
O último grupo de funções possui parâmetro nominal e não obrigatório. O mecanismo é parecido
com as do grupo 5, porém agora a passagem é feita de modo nominal e não posicional, o que nos
permite acessar tanto o valor do parâmetro quanto o nome da variável que o armazena. Veja a
função "imprimir_parametros" a seguir:
In [13]:
def imprimir_parametros(**kwargs):
print(f"Tipo de objeto recebido = {type(kwargs)}\n")
qtde_parametros = len(kwargs)
print(f"Quantidade de parâmetros = {qtde_parametros}")
print("\nChamada 1")
imprimir_parametros(cidade="São Paulo", idade=33, nome="João")
print("\nChamada 2")
imprimir_parametros(desconto=10, valor=100)
Chamada 1
Tipo de objeto recebido = <class 'dict'>
Quantidade de parâmetros = 3
variável = cidade, valor = São Paulo
variável = idade, valor = 33
variável = nome, valor = João
Chamada 2
Tipo de objeto recebido = <class 'dict'>
Quantidade de parâmetros = 2
variável = desconto, valor = 10
variável = valor, valor = 100
A função "imprimir_parametros" na entrada 13 (In [13]) foi definida de modo a obter parâmetros
nominais arbitrários. Tal construção é feita, passando como parâmetro o **kwargs. O parâmetro
não precisa ser chamado de kwargs, mas é uma boa prática. Já os dois asteriscos antes do parâmetro
é obrigatório. Na linha 2, estamos imprimindo o tipo de objeto recebido, você pode ver na saída que
é um dict (dicionário), o qual estudaremos nas próximas aulas. Na linha 3, usamos a função built-in
len() (length) para saber a quantidade de parâmetros que foram passados. Como se trata de
parâmetros nominais não definidos, conseguimos acessar o nome da variável em que estão
atribuídos o valor e o próprio valor do argumento, usando a estrutura de repetição "for" e a função
items() na linha 17. A função items não é built-in, ela pertence aos objetos do tipo dicionário, por
isso a chamada é feita como "kwargs.items()" (ou seja, objeto.função). Agora observe as chamadas
feitas nas linhas 11 e 14, cada uma com uma quantidade diferente de argumentos, mas veja na saída
que os argumentos estão associados ao nome da variável que foi passado.
Utilize o emulador a seguir para testar os códigos e criar novas funções para explorar as diferentes
formas de construir uma função e passar parâmetros.
FUNÇÕES ANÔNIMAS EM PYTHON
Já que estamos falando sobre funções, não podemos deixar de mencionar um poderoso recurso da
linguagem Python: a expressão "lambda". Expressões lambda (às vezes chamadas de formas
lambda) são usadas para criar funções
anônimas https://docs.python.org/3/reference/expressions.html#lambda. Uma função anônima é
uma função que não é construída com o "def" e, por isso, não possui nome. Esse tipo de construção
é útil, quando a função faz somente uma ação e é usada uma única vez. Observe o código a seguir:
In [14]:
(lambda x: x + 1)(x=3)
Out[ ]:
4
Na entrada 14 (In [14]), criamos uma função que recebe como parâmetro um valor e retorna esse
valor somado a 1. Para criar essa função anônima, usamos a palavra reservada "lambda" passando
como parâmetro "x". O dois pontos é o que separa a definição da função anônima da sua ação, veja
que após os dois pontos, é feito o cálculo matemático x + 1. Na frente da função, já a invocamos
passando como parâmetro o valor x=3, veja que o resultado é portanto 4.
A função anônima pode ser construída para receber mais de um parâmetro. Observe o código a
seguir:
In [15]:
(lambda x, y: x + y)(x=3, y=2)
Out[ ]:
5
Na entrada 15 (In [15]), criamos uma função anônima que recebe como parâmetro dois valores e
retorna a soma deles. Para criar essa função anônima, usamos a palavra reservada "lambda"
passando como parâmetro "x, y". Após os dois pontos, é feito o cálculo matemático x + y. Na frente
da função, já a invocamos passando como parâmetro o valor x=3 e y=2, veja que o resultado é
portanto 5.
A linguagem Python, nos permite atribuir a uma variável uma função anônima, dessa forma, para
invocar a função, fazemos a chamada da variável. Observe o código a seguir:
In [16]:
somar = lambda x, y: x + y
somar(x=5, y=3)
Out[ ]:
8
Na entrada 16 (In [16]), criamos uma função anônima que recebe como parâmetro dois valores e
retorna a soma deles, essa função foi atribuída a uma variável chamada "somar". Veja que na linha
2, fazemos a chamadada função através do nome da variável, passando os parâmetros que ela
requer.
Na próxima aula, vamos aprender sobre outros tipos de dados em Python e voltaremos a falar mais
sobre as funções lambda aplicadas nessas estruturas.
MANZANO, J. A. N. G; OLIVEIRA, J. F. de. Estudo Dirigido de Algoritmos. 15. ed. São Paulo:
Érica, 2012.