Funções
Live de Python #250 - #251 - #252
● Fornecer um glossário a quem estiver começando
● Fundamentação teórica a quem já tem bagagem
● Explorar lugares não tão comuns
● Ser um hub de outras lives
Objetivos dessa live
● Fornecer um glossário a quem estiver começando
● Fundamentação teórica a quem já tem bagagem
● Explorar lugares não tão comuns
● Ser um hub de outras lives
PS: Vamos no modo lento, perguntem com força, podemos dividir essa live em
duas partes e terminar esse assunto na próxima live!
Objetivos dessa live
PS!
Roteiro
1. Subprogramas 3. Corpo
O que são? Quais suas formas? Como Subprogramas, funções, geradores,
são chamadas? Quais seus tipos? subgeradores, …
2. Cabeçalho 4. O objeto
Parâmetros de N formas, argumentos, Funções como objeto, funções de ordem
anotações, fluxo, … superior, funções em estruturas, …
[Link]/livedepython [Link]@[Link] [Link]/dunossauro
Ajude o projeto <3
Ademar Peixoto, Adilson Herculano, Adriano Ferraz, Alemao, Alexandre Harano, Alexandre Lima, Alexandre Takahashi, Alexandre
Villares, Alex Lima, Alfredo Braga, Alisson Souza, Alysson Oliveira, Andre Azevedo, Andre Mesquita, Andre Paula, Aquiles Coutinho,
Arnaldo Turque, Aslay Clevisson, Aurelio Costa, Ayr-ton, Bernardo At, Bruno Almeida, Bruno Barcellos, Bruno Freitas, Bruno Lopes,
Bruno Ramos, Caio Nascimento, Carlos Ramos, Christian Semke, Claudemir Firmino, Cristian Firmino, Damianth, Daniel Freitas,
Daniel Wojcickoski, Danilo Boas, Danilo Segura, Danilo Silva, David Couto, David Kwast, Davi Goivinho, Davi Souza, Dead Milkman,
Delton Porfiro, Denis Bernardo, Diego Farias, Diego Guimarães, Dilenon Delfino, Dino, Diogo Paschoal, Edgar, Edilson Ribeiro, Eduardo
Silveira, Eduardo Tolmasquim, Emerson Rafael, Erick Andrade, Érico Andrei, Everton Silva, Fabiano, Fabiano Tomita, Fabio Barros,
Fábio Barros, Fabio Correa, Fábio Thomaz, Fabricio Biazzotto, Fabricio Patrocinio, Felipe Augusto, Felipe Rodrigues, Fernanda Prado,
Fernando Celmer, Firehouse, Flávio Meira, Francisco Neto, Francisco Silvério, Gabriel Espindola, Gabriel Mizuno, Gabriel Paiva, Gabriel
Ramos, Gabriel Simonetto, Geandreson Costa, Geizielder, Giovanna Teodoro, Giuliano Silva, Guilherme Felitti, Guilherme Gall,
Guilherme Piccioni, Guilherme Silva, Guionardo Furlan, Gustavo Suto, Haelmo, Haelmo Almeida, Harold Gautschi, Heitor Fernandes,
Helvio Rezende, Henrique Andrade, Higor Monteiro, Italo Silva, Janael Pinheiro, Jean Victor, Jefferson Antunes, Joelson Sartori,
Jonatas Leon, Jônatas Silva, Jorge Silva, José Gomes, Joseíto Júnior, Jose Mazolini, Josir Gomes, Juan Felipe, Juan Gutierrez,
Juliana Machado, Julio Franco, Júlio Gazeta, Júlio Sanchez, Julio Silva, Kaio Peixoto, Kálita Lima, Leandro Silva, Leandro Vieira,
Leonardo Mello, Leonardo Nazareth, Lucas Carderelli, Lucas Mello, Lucas Mendes, Lucas Nascimento, Lucas Pavelski, Lucas
Schneider, Lucas Simon, Luciano Filho, Luciano Ratamero, Luciano Teixeira, Luis Eduardo, Luiz Duarte, Luiz Lima, Luiz Paula,
Mackilem Laan, Marcelo Araujo, Marcelo Campos, Marcio Moises, Marco Mello, Marcos Gomes, Marina Passos, Mateus Lisboa,
Mateus Ribeiro, Mateus Silva, Matheus Silva, Matheus Vian, Mírian Batista, Mlevi Lsantos, Murilo Carvalho, Murilo Viana, Natan
Cervinski, Nathan Branco, Ocimar Zolin, Otávio Carneiro, Patricia Minamizawa, Patrick Felipe, Pedro Henrique, Pedro Pereira, Peterson
Santos, Pytonyc, Rafael Faccio, Rafael Lopes, Rafael Romão, Raimundo Ramos, Ramayana Menezes, Regis Santos, Renato José,
Renato Oliveira, Renê Barbosa, Rene Bastos, Rene Pessoto, Ricardo Silva, Riverfount, Rjribeiro, Robson Maciel, Rodrigo Barretos,
Rodrigo Oliveira, Rodrigo Quiles, Rodrigo Vaccari, Rodrigo Vieira, Rui Jr, Samanta Cicilia, Samuel Santos, Selmison Miranda, Téo Calvo,
Thiago Araujo, Thiago Borges, Thiago Curvelo, Thiago Souza, Tony Dias, Tyrone Damasceno, Valdir, Valdir Tegon, Vinicius Stein,
Walter Reis, Willian Lopes, Wilson Duarte, Yros Aguiar, Zeca Figueiredo
Obrigado você
Sub
progra
mas O que são?
Funções
Na programação, funções são casos especiais de subprogramas.
subprograma
subprograma
subprograma
subprograma
Input Output
Programa
"Um subprograma é uma abstração de
processo, encapsulada, reutilizável, que
geralmente tem um nome e pode ser
parametrizável."
Subprograma [definição pessoal]
Subprograma
Um subprograma é uma
● abstração de processo (uma lista de passos)
● encapsulada (com sua lógica isolada),
● reutilizável (pode ser chamada diversas vezes),
● que geralmente tem um nome e
● pode ser parametrizável.
Exemplo de subprograma [[Link]
Exemplo de subprograma [[Link]
nome
Passos
Parâmetros
Subprograma
Um subprograma é uma
● abstração de processo (uma lista de passos)
● encapsulada (com sua lógica isolada),
● reutilizável (pode ser chamada diversas vezes),
● que geralmente tem um nome e
● pode ser parametrizável.
Chamada e Reutilização
As chamadas de subprogramas são feitas a partir do seu nome, seguido por ().
São reutilizáveis, pois podem ser chamadas diversas vezes
* chamada é um termo técnico, em inglês refere-se a Callable [falaremos mais disso lá na frente]
Subprograma
Um subprograma é uma
● abstração de processo (uma lista de passos)
● encapsulada (com sua lógica isolada),
● reutilizável (pode ser chamada diversas vezes),
● que geralmente tem um nome e
● pode ser parametrizável.
Explicar aqui abstração e encapsulamento!
Tipos de subprogramas
Existem duas categorias distintas de subprogramas:
1. Procedimentos [procedures]: Não retornam valores
2. Funções: Retornam valores
Exemplo de um procedimento
Procedimentos
A ideia por trás dos procedimentos é executar uma tarefa e pode retornar
seus valores através da manipulação do escopo global
Função
Já a função se baseia somente no estado dos parâmetros recebidos via
argumentos durante a chamada.
Parâmetros
Argumentos
Efeitos colaterais
Dizemos que quando um subprograma altera variáveis [estado] fora do seu
escopo interno ele gera um efeito colateral na aplicação
Funções puras
Dizemos que uma função que não gera efeitos colaterais é uma função
pura. Pois ela manipula somente os parâmetros, os transforma e retorna
um resultado
Transformação
A ideia por trás de uma função é transformar um dado em outro
f( ):
Falando em funções
Existem duas palavras reservadas para criar uma função em Python:
lambda def
Funções lambda
A ideia por trás de uma função lambda é que ela não tenha um nome, seja
anônima. Funções lambda em python são limitadas a uma única
expressão. Onde `lambda` é o statement que define a função, `x` é o
parâmetro dessa função e `x + 1` é o copo da função. O resultado da
expressão é o que será retornado
Def
Já o statement `def` define uma função nomeada, que pode ser chamada
no futuro e ser reutilizada.
Partes de um subprograma
Costumamos dividir os subprogramas em duas partes
Cabeçalho
Corpo
Às vezes temos Docstring :)
Nome, tipos de
parâmetros,
Cabe
anotações,
… çalho
Cabeçalho
O cabeçalho da função é a interface com que o programa, a unidade
chamadora, vai interagir com o subprograma. Ele é formado por:
● Nome
● Argumentos, opcional
● Anotação de tipo de retorno, opcional
● Definição de tipo genérico, opcional
Cabeçalho
Nomes de subprogramas
Existem boas práticas e também algumas limitações para
criação de nomes:
1. Não podem iniciar com números e caracteres
especiais
2. Devem usar sempre letras minusculas (PEP-8)
3. Devem separar palavras com underline [snake_case]
(PEP-8)
4. *Em alguns casos, a biblioteca padrão apresenta
nomes em mixedCase, pois foram definidas antes de
2001, criação da PEP-8
Parâmetros
A forma tradicional de fornecer dados a subprogramas é com a passagem
de argumentos durante a chamada do mesmo.
Parâmetros são uma espécie de variáveis internas usadas durante a
definição de um subprograma.
* Na literatura você pode encontrar a nomenclatura parâmetros reais para argumentos e parâmetros formais para parâmetros!
Tipos de parâmetros
Existem diversos tipos de parâmetros que podemos usar em python:
● Posicionais: Que dependem que quem usa a interface saiba qual a
ordem de chama dos parâmetros
● Chave-Valor [nomeados]: Que podem ser chamados independe da ordem,
mas é necessário saber o nome do parâmetro
0 1
Posicionais e chave-valor
Por padrão, os parâmetros em python são "híbridos", pode ser chamados
tanto como posicionais, quanto nomeados. Tendo somente a restrição de
que após a aparição de um parâmetro nomeado, todos os seguintes
devem ser nomeados também
Restrições em parâmetros
Os parâmetros têm mecanismos de restrição para que parâmetros sejam
exclusivamente posicionais ou exclusivamente nomeados. Os parâmetros
/ e * respectivamente:
Restrições em parâmetros
Os parâmetros têm mecanismos de restrição para que parâmetros sejam
exclusivamente posicionais ou exclusivamente nomeados. Os parâmetros
/ e * respectivamente:
Empacotamento de parâmetros
Em alguns momentos pode existir uma limitação por conta dos
parâmetros, não sabemos quantos vamos receber, ou propositalmente
esperar um número incontável de argumentos. Para isso temos o
empacotamento [star args em inglês]
Empacotamento de parâmetros
Em alguns momentos pode existir uma limitação por conta dos
parâmetros, não sabemos quantos vamos receber, ou propositalmente
esperar um número incontável de argumentos. Para isso temos o
empacotamento [star args em inglês]
Empacotamento de parâmetros
Também podemos empacotar parâmetros nomeados usando dois **
KWARGS = Key-Word arguments = Argumentos de chave-valor
Empacotamento de parâmetros
Também podemos empacotar parâmetros nomeados usando dois **
Subprogramas como argumento
Uma propriedade especial de funções em python é o fato delas serem
objetos também. O quer dizer que as funções também pode ser passadas
como argumentos. Chamamos isso de Função de ordem superior [High
order function]. Aqui as funções anônimas brilham.
Subprogramas como argumento
Uma propriedade especial de funções em python é o fato delas serem
objetos também. O quer dizer que as funções também pode ser passadas
como argumentos. Chamamos isso de Função de ordem superior [High
order function]. Aqui as funções anônimas brilham.
Anotação de parâmetros
Uma frente recente na linguagem (3.5+) tem aderido às dicas de tipo, para
explicar a aplicações externas quais são os tipos esperados pelos
parâmetros. A sintaxe definida é `parâmetro: tipo`:
Anotação de retorno
Em conjunto com esses metadados, também foi inserida a anotação para
o retorno da função. Para isso descrevemos no cabeçalho o tipo de dado
que uma função retorna. A sintaxe é ` -> tipo`
Variáveis de tipo
Na versão 3.12 do python foi introduzido o contexto para variáveis de
tipos genéricos no cabeçalho dos subprogramas, adicionando uma
variável genérica após o nome
Em breve falaremos MUITO mais sobre isso!
A parte interna do
subprograma! Corpo
Corpo [lambda]
O corpo dos subprogramas são responsáveis pela computação que
ocorrerá quando o subprograma for chamado
Corpo [lambda]
As funções lambda tem um comportamento diferente de funções
tradicionais, elas não necessitam da palavra return. O resultado da
expressão sempre será o retorno dela
Corpo [def]
Já o corpo de subprogramas definidos com def podem conter N
expressões e linhas dentro de seu corpo
Função x Procedimento
O que pode diferenciar uma função de um procedimento em defs é o uso
da palavra return.
Função x Procedimento
O que pode diferenciar uma função de um procedimento em defs é o uso
da palavra return. Em outras linguagens de programação existe uma
palavra usada no cabeçalho para dizer que não haverá retorno: void
Função x Procedimento
Um comportamento interessante em python é que não existem
procedimentos formais. Toda def é em teoria uma função, pois caso não
exista return. O interpretador retornará None
Aninhamento
Um dos conceitos mais interessantes do corpo dos subprogramas é a
possibilidade de definir subprogramas dentro de subprogramas.
Aninhamento
Um dos conceitos mais interessantes do corpo dos subprogramas é a
possibilidade de definir subprogramas dentro de subprogramas.
Aninhamento com defs
Também podemos aninhar subprogramas nomeados.
Aninhamento com defs
Também podemos aninhar subprogramas nomeados.
Dá até pra juntar :)
Compartilhamento de escopo
Uma das grandes vantagens de criar subprogrmas aninhados é que você
pode atribuir estados definidos para os mesmos.
O valor de X fica
na "memoria" de
inner
Closure
Damos o nome de closure para essa referência a variável que está na
"memória" da função interna.
Closure
Damos o nome de closure para essa referência a variável que está na
"memória" da função interna.
Dizemos que X é
uma variável livre
Closure
Damos o nome de closure para essa referência a variável que está na
"memória" da função interna.
Dizemos que X é
uma variável livre
Esses valores são armazenados no objeto
Vamos falar sobre isso lá na frente, mas esses valores estão nessas
variáveis:
Fluxo
O fluxo segue como qualquer código imperativo, ele é lido linha a linha.
Mas nem sempre!
Fluxo
Uma das coisas que vimos até agora é quem um subprograma é sempre
chamado por uma unidade chamadora, toma o controle e quando sua
execução termina, o controle é retomado por quem fez a sua chamada.
sub A
Chamador
sub B
Corrotinas
As corrotinas são uma forma de um modelo de controle de unidades
simétrico[symmetric unit control model]. Onde a responsabilidade é dividia
com o subprograma em um sistema de retomadas[resume].
.
. .
retome B .
. retome A
. .
retome B .
. .
. retome A
Corrotinas
As corrotinas em python são atualmente divididas em duas categorias. As
corrotinas clássicas e as corrotinas assíncronas.
Corrotinas
Geradores
Um dos tipos mais tradicionais de corrotina são os geradores*. Geradores
são criadores de dados com a condição simétrica de parada. Eles são a
implementação do protocolo de iteração usando subprogramas.
next next next
yield value yield value yield value
next
StopIteration
Geradores
Iteráveis em python são coisas "desmontáveis", que conseguimos pegar
as partes. Da forma como fazemos em um for.
Geradores
A ideia desse tipo de subprograma é gerar valores.
Exemplo de gerador
Geradores podem ser infinitos e por contar com o controle simétrico
podem ser continuados
Exemplo de gerador
Essa condição de só
Geradores podem ser infinitos e por contarcalcular quando
com o controle for
simétrico
podem ser continuados chamado, por conta da
simetria, se chama
Avaliação preguiçosa
[lazy evaluation]
Sub Geradores
Uma das condições especiais de geradores é que eles podem delegar
uma tarefa a outro gerador. Chamamos de sub geradores.
Sub Geradores
Uma das condições especiais de geradores é que eles podem delegar
uma tarefa a outro gerador. Chamamos de sub geradores.
Corrotinas
Embora os geradores sejam corrotinas, quando nos referimos
especificamente a corrotinas, queremos aproveitar a condição de parada
para delegar uma tarefa específica ao subprograma.
Podemos usar o yield como expressão e passar valores usando o método
send:
Corrotinas
Embora os geradores sejam corrotinas, quando nos referimos
especificamente a corrotinas, queremos aproveitar a condição de parada
para delegar uma tarefa específica ao subprograma.
Podemos usar o yield como expressão e passar valores usando o método
send:
Um exemplo legal!
Exemplo de média cumulativa adaptado do fluent python (16.3)
Corrotinas
Existe outro caso de uso além dos geradores com yield que são as
corrotinas.
O corpo de um subprograma
O corpo de um subprograma pode delimitar comportamentos
completamente diferentes. Nesse ponto, chegamos em diferentes tipos de
subprogramas. Palavras reservadas que podem ser encontradas em
subprogramas:
● yield: Um subprograma em um gerador / corrotina
● yield from: Transforma o subprograma em um sub gerador
● return: Diz que o subprograma é uma função
● _: Caso nenhuma dessas coisas ocorra em nenhuma def, ela pode ser
considerada um procedimento
Tipos de subprogramas
Corrotinas abrem espaço para assincronismo!
Além das corrotinas clássicas que vimos. Temos as corrotinas assíncronas
Isso é assunto pra outro momento!
Funções também
são Objetos
Funções são objetos
Uma das propriedades interessantes do python, e de outras linguagens
também, é que funções são objetos.
O que isso quer dizer?
Quer dizer que funções podem ser usadas como qualquer outro objeto.
Elas podem ser:
● Atribuídas a variáveis
● Inseridas em containers (listas, dicionários, etc.)
● Passadas como parâmetros
● Retornadas por funções
● …
Um exemplo básico
Sempre gosto de iniciar com um exemplo simples, mas que ajuda a
entender
Funções recebendo funções
Esse é o conceito por trás de diversas funções da biblioteca padrão do
python, como:
● map
● filter
● sorted
● [Link]
● [Link]
● …
Funções vs loops
Uma das formas mais comuns de usar funções como objeto é poder evitar
o uso de loops como for e while. Transformando a maneira imperativa de
se programar, para uma forma declarativa.
Gerador!
Funções vs Loops
O retorno de funções
Outro ponto interessante é o fato de poder retornar funções. Casos usados
por closures e decoradores. Um bom exemplo é a função partial em
conjunto com o módulo operator
O retorno de funções
Outro ponto interessante é o fato de poder retornar funções. Casos usados
por closures e decoradores. Um bom exemplo é a função partial em
conjunto com o módulo operator
Juntando conceitos
Sabemos que uma função pode:
1. Ser colocada em um container (Objeto)
2. Receber uma função (HOF)
3. Retornar uma função (HOF)
4. Ser definida dentro de outra (Nested)
5. Carregar um estado interno (Closure)
Podemos explorar um pouco mais a união desses conceitos!
Juxt
Juxt é uma função tradicional em linguagens de programação funcional.
Ela é uma função que cria uma função que aplica uma lista de funções a
um mesmo valor. Resultado em uma lista de valores aplicados as funções
recebidas.
( [f1, f2, f3, f4], val ) -> [f1(val), f2(val), f3(val), f4(val)]
Para simplificar, vamos imaginar um cenário de validação de dados. Para
uma string ser válida, ela tem que ser maior 3, menor que 10 e ter o
caractere @:
[gt_3, lt_10, has_at] -> [gt_3(str), lt_10(str), has_at(str)]
Pensando em uma implementação!
Uma básica, para entrarmos nos trilhos! Não é reutilizável!
Tentando uma HOF
Podemos reutilizar, mas o dado e as funções tem que ser passadas juntas.
Juxt
Se adicionarmos a closure, vamos ter um validador independente. Além de
criarmos uma fábrica deles!
Aplicando o mesmo conceito, mas diferente
A aplicação de funções de forma consecutiva, uma composição de
funções:
f1 f2
A B C
f2(f1(x))
Aplicando o mesmo conceito, mas diferente
Exemplo de uso
Puro suco das funções
Classes também podem!
Trabalhando com objetos imutáveis
Uma característica interessante
Como dissemos a alguns slides atrás, em python, pelo fato de "tudo ser
objeto", qualquer objeto que implemente a interface para ser chamável,
pode se comportar como subprograma:
[Link]/livedepython [Link]@[Link] [Link]/dunossauro
Ajude o projeto <3