Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 1 
 
SUMÁRIO 
Introdução .................................................................................................................................................. 9 
Classificação das linguagens de programação ..................................................................................... 9 
Razões para estudarmos linguagens de programação .............................................................................. 9 
Linguagem de programação e produtividade do programador ............................................................... 9 
O papel da abstração nas linguagens de programação ....................................................................... 10 
Classificação das linguagens de programação ........................................................................................ 12 
Classificação por nível.......................................................................................................................... 12 
Classificação por gerações ...................................................................................................................... 14 
Linguagens de 1ª geração (linguagem de máquina) ............................................................................ 14 
Linguagens de 2ª geração (linguagem de montagem – assembly) ...................................................... 14 
Linguagens de 3ª geração (linguagens procedurais) ........................................................................... 15 
Linguagens de 4ª geração (linguagens aplicativas) ............................................................................. 16 
Linguagens de 5ª geração (voltadas à inteligência artificial) ................................................................ 16 
Verificando o aprendizado ........................................................................................................................ 16 
Critérios de avaliação de linguagens de programação ................................................................... 17 
Domínios da programação ....................................................................................................................... 17 
Aplicações científicas (máquinas de calcular com alta precisão) ......................................................... 17 
Aplicações comerciais .......................................................................................................................... 18 
Aplicações com inteligência artificial .................................................................................................... 18 
Programação de sistemas .................................................................................................................... 18 
Programação para web ........................................................................................................................ 18 
Programação mobile ............................................................................................................................ 19 
Avaliação de linguagens de programação ............................................................................................... 19 
Legibilidade .............................................................................................................................................. 20 
Simplicidade ......................................................................................................................................... 20 
Ortogonalidade ..................................................................................................................................... 20 
Instruções de controle .......................................................................................................................... 21 
Tipos e estruturas de dados ................................................................................................................. 21 
Sintaxe ................................................................................................................................................. 21 
Facilidade de escrita (redigibilidade) ........................................................................................................ 21 
Simplicidade e ortogonalidade ............................................................................................................. 21 
Expressividade ..................................................................................................................................... 22 
Suporte para a abstração ..................................................................................................................... 22 
Confiabilidade........................................................................................................................................... 22 
Verificação de tipos .............................................................................................................................. 22 
Tratamento de exceção ........................................................................................................................ 22 
Aliasing (apelidos) ................................................................................................................................ 22 
Legibilidade e facilidade de escrita ....................................................................................................... 23 
Custo ........................................................................................................................................................ 23 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 2 
 
Verificando o aprendizado ........................................................................................................................ 23 
Os paradigmas e suas características ............................................................................................. 24 
Paradigma imperativo .............................................................................................................................. 24 
Paradigma estruturado ......................................................................................................................... 24 
Paradigma orientado a objetos ............................................................................................................. 25 
Paradigma concorrente ........................................................................................................................ 25 
Paradigma declarativo .............................................................................................................................. 26 
Paradigma funcional ............................................................................................................................. 26 
Paradigma lógico .................................................................................................................................. 27 
Verificando o aprendizado ........................................................................................................................ 27 
Métodos de implementação das linguagens ................................................................................... 27 
Tradução .................................................................................................................................................. 28 
Compilador ........................................................................................................................................... 28 
Interpretação ............................................................................................................................................ 30 
Principais características do interpretador............................................................................................31 
Tradução x interpretação...................................................................................................................... 31 
Sistemas híbridos ..................................................................................................................................... 32 
Sistema de implementação de Python ................................................................................................. 32 
Verificando o aprendizado ........................................................................................................................ 32 
Considerações finais ................................................................................................................................ 33 
Referências .............................................................................................................................................. 33 
Explore+ ................................................................................................................................................... 33 
Python Básico ...................................................................................................................................... 34 
Introdução ................................................................................................................................................ 34 
Linguagem Python e suas principais características ...................................................................... 34 
Conceitos ................................................................................................................................................. 34 
Características da linguagem Python ....................................................................................................... 34 
Instalação ................................................................................................................................................. 36 
Utilitários e módulos ................................................................................................................................. 36 
Blocos ...................................................................................................................................................... 36 
Comentários ............................................................................................................................................. 37 
Boas práticas de programação................................................................................................................. 37 
Verificando o aprendizado ........................................................................................................................ 38 
Uso de variáveis em Python ............................................................................................................ 38 
Conceitos ................................................................................................................................................. 38 
Identificadores de variáveis ...................................................................................................................... 39 
Amarrações .............................................................................................................................................. 40 
Amarração de tipo ................................................................................................................................ 41 
Escopo de visibilidade .............................................................................................................................. 41 
Variáveis globais .................................................................................................................................. 41 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 3 
 
Variáveis locais .................................................................................................................................... 42 
Tipos de escopo ................................................................................................................................... 43 
Tempo de vida.......................................................................................................................................... 44 
Constantes ............................................................................................................................................... 44 
Verificando o aprendizado ........................................................................................................................ 44 
Tipos de dados e as expressões em Python ................................................................................... 45 
Conceitos ................................................................................................................................................. 45 
Tipos numéricos ....................................................................................................................................... 45 
O tipo int ............................................................................................................................................... 45 
O tipo float ............................................................................................................................................ 46 
O tipo complex ..................................................................................................................................... 48 
O tipo bool ............................................................................................................................................ 49 
Operadores numéricos ............................................................................................................................. 50 
Operadores matemáticos ..................................................................................................................... 50 
Operadores booleanos ......................................................................................................................... 51 
Tipos sequenciais ..................................................................................................................................... 51 
Strings .................................................................................................................................................. 52 
Listas .................................................................................................................................................... 53 
Tuplas................................................................................................................................................... 53 
Range ................................................................................................................................................... 53 
Operadores sequenciais comuns ......................................................................................................... 54 
Dicionários................................................................................................................................................ 54 
Precedência de operadores ..................................................................................................................... 55 
Conversões de tipos ................................................................................................................................. 55 
Verificando o aprendizado ........................................................................................................................ 57 
Formas de atribuição, de entrada e saída de dados em Python .................................................... 57 
Conceitos .................................................................................................................................................57 
Sentenças de atribuição ........................................................................................................................... 57 
Atribuição simples ................................................................................................................................ 57 
Atribuição múltipla ................................................................................................................................ 57 
Operadores de atribuição compostos ................................................................................................... 58 
Troca de variáveis ................................................................................................................................ 59 
O primeiro programa em python............................................................................................................... 60 
Saída de dados com a função print() ................................................................................................... 61 
Entrada de dados com a função input() ................................................................................................... 62 
A função eval() ..................................................................................................................................... 64 
Mão na massa .......................................................................................................................................... 65 
Saída formatada de dados ....................................................................................................................... 65 
Impressão de sequências..................................................................................................................... 67 
Verificando o aprendizado ........................................................................................................................ 68 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 4 
 
Considerações finais ................................................................................................................................ 69 
Referências .............................................................................................................................................. 69 
Explore+ ................................................................................................................................................... 69 
Python Estruturado .............................................................................................................................. 70 
Introdução ................................................................................................................................................ 70 
Estruturas de decisão e repetição em Python ................................................................................. 70 
Tratamento das condições ....................................................................................................................... 70 
As Estruturas de decisão If, If-Else E Elif ................................................................................................. 70 
Estrutura de repetição for ......................................................................................................................... 71 
As listas do tipo range() ........................................................................................................................ 71 
A sintaxe da estrutura for ..................................................................................................................... 72 
O laço for com uma string .................................................................................................................... 72 
Uso do laço for com qualquer sequência ............................................................................................. 72 
Estrutura de repetição while ..................................................................................................................... 73 
O laço while infinito .............................................................................................................................. 74 
As instruções auxiliares break, continue e pass ....................................................................................... 74 
A instrução break ................................................................................................................................. 74 
A instrução continue ............................................................................................................................. 74 
A instrução pass ....................................................................................................................................... 75 
Verificando o aprendizado ........................................................................................................................ 75 
Principais conceitos de subprogramas e a sua utilização em Python ............................................ 76 
Características gerais dos subprogramas ................................................................................................ 76 
Definições básicas ................................................................................................................................... 76 
Parâmetros ............................................................................................................................................... 77 
Procedimentos e funções ......................................................................................................................... 78 
Ambientes de referenciamento local ........................................................................................................ 78 
Variáveis locais .................................................................................................................................... 78 
Subprogramas aninhados .................................................................................................................... 80 
Métodos de passagens de parâmetros .................................................................................................... 80 
Recursividade........................................................................................................................................... 80 
A função recursiva fatorial .................................................................................................................... 81 
A sequência de Fibonacci .................................................................................................................... 82 
Docstrings ................................................................................................................................................ 82 
Verificando o aprendizado ........................................................................................................................ 83 
Uso correto de recursos de bibliotecas em Python ......................................................................... 83 
Biblioteca padrão python .......................................................................................................................... 83 
Como usar uma função de módulo importado.......................................................................................... 84 
Módulo math............................................................................................................................................. 84 
Módulo random ........................................................................................................................................ 84 
Distribuições de valores reais ............................................................................................................... 85 
Apostila de Paradigmas de Linguagensde Programação em Python 
Marcio Quirino - 5 
 
Funções para números inteiros ............................................................................................................ 85 
Funções para sequências .................................................................................................................... 85 
Módulo smtplib ......................................................................................................................................... 85 
Módulo time .............................................................................................................................................. 86 
Módulo tkinter ........................................................................................................................................... 87 
Usando pacotes externos ......................................................................................................................... 89 
Criação do próprio módulo ....................................................................................................................... 91 
Verificando o aprendizado ........................................................................................................................ 91 
Formas de tratamento de exceções e eventos em Python ............................................................. 92 
Erros e exceções ...................................................................................................................................... 92 
Captura e manipulação de exceções ....................................................................................................... 93 
Captura de exceções de determinado tipo ........................................................................................... 94 
Captura de exceções de múltiplos tipos ............................................................................................... 94 
O tratamento completo das exceções .................................................................................................. 94 
Tratamento de eventos ............................................................................................................................ 94 
Verificando o aprendizado ........................................................................................................................ 95 
Considerações finais ................................................................................................................................ 95 
Referências .............................................................................................................................................. 95 
Explore+ ................................................................................................................................................... 95 
Python Orientado a Objetos ................................................................................................................ 96 
Definição .................................................................................................................................................. 96 
Propósito .................................................................................................................................................. 96 
Preparação ............................................................................................................................................... 96 
Introdução ................................................................................................................................................ 96 
Conceitos gerais da orientação a objetos ........................................................................................ 96 
Conceitos de POO - programação orientada a objetos ............................................................................ 96 
Pilares da orientação a objetos ................................................................................................................ 97 
Objetos ................................................................................................................................................. 97 
Atributos ............................................................................................................................................... 97 
Operações ............................................................................................................................................ 97 
Classes................................................................................................................................................. 98 
Encapsulamento ....................................................................................................................................... 99 
Herança .................................................................................................................................................... 99 
Herança simples ................................................................................................................................. 100 
Herança múltipla ................................................................................................................................ 101 
Polimorfismo........................................................................................................................................... 101 
Verificando o aprendizado ...................................................................................................................... 102 
Conceitos básicos da programação orientada a objetos na linguagem Python ........................... 103 
Classes e objetos em Python ................................................................................................................. 103 
Definição de classe ................................................................................................................................ 103 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 6 
 
Construtores e self ............................................................................................................................. 103 
Métodos.............................................................................................................................................. 104 
Métodos com retorno.......................................................................................................................... 105 
Referências entre objetos na memória ............................................................................................... 105 
Agregação .............................................................................................................................................. 107 
Composição ........................................................................................................................................... 108 
Encapsulamento ..................................................................................................................................... 110 
Atributos públicos e privados .............................................................................................................. 110 
Decorator @property .......................................................................................................................... 111 
Atributos de classe ............................................................................................................................. 111 
Métodos de classe ............................................................................................................................. 112 
Métodos públicos e privados .............................................................................................................. 113 
Métodos estáticos ..............................................................................................................................113 
Verificando o aprendizado ...................................................................................................................... 114 
Conceitos da orientação a objetos como Herança e Polimorfismo .............................................. 114 
Herança e polimorfismo ......................................................................................................................... 114 
Herança .................................................................................................................................................. 114 
Herança Múltipla ................................................................................................................................ 116 
Polimorfismo........................................................................................................................................... 118 
Classes abstratas ................................................................................................................................... 120 
Exceções ................................................................................................................................................ 121 
Verificando o aprendizado ...................................................................................................................... 121 
OO aplicados a Python com outras linguagens OO existentes no mercado ................................ 122 
Linguagem de programação orientadas a objetos ................................................................................. 122 
Comparação com C++ e Java ................................................................................................................ 122 
Instanciação de objetos ...................................................................................................................... 122 
Construtores de objetos ..................................................................................................................... 122 
Modificadores de acesso atributos ..................................................................................................... 123 
Herança múltipla de classes................................................................................................................... 123 
Classes sem definição formal................................................................................................................. 123 
Tipos primitivos ...................................................................................................................................... 123 
Interfaces ............................................................................................................................................... 124 
Sobrecarga de métodos ......................................................................................................................... 124 
Tabela Comparativa ........................................................................................................................... 124 
Verificando o aprendizado ...................................................................................................................... 124 
Considerações finais .............................................................................................................................. 125 
Referências ............................................................................................................................................ 125 
Explore+ ................................................................................................................................................. 126 
Python em Outros Paradigmas .......................................................................................................... 127 
Introdução .............................................................................................................................................. 127 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 7 
 
Linguagem funcional e sua utilização em Python ......................................................................... 127 
Introdução .............................................................................................................................................. 127 
Funções puras........................................................................................................................................ 128 
Dados imutáveis ..................................................................................................................................... 128 
Efeito colateral e estado da aplicação .................................................................................................... 129 
Funções de ordem superior.................................................................................................................... 130 
Funções lambda ..................................................................................................................................... 131 
Não utilizar loops .................................................................................................................................... 132 
Map ........................................................................................................................................................ 132 
Filter ....................................................................................................................................................... 133 
Script FUNÇÃO_FILTRO_ITERABLE.PY .......................................................................................... 134 
Script FUNCAO_FILTER.PY .............................................................................................................. 134 
Script, FUNÇÃO_FILTER_LAMBDA.PY ............................................................................................ 134 
Verificando o aprendizado ...................................................................................................................... 134 
Computação concorrente e sua utilização em Python .................................................................. 135 
Introdução .............................................................................................................................................. 135 
Conceitos ............................................................................................................................................... 135 
Programas e processos...................................................................................................................... 135 
Concorrência e paralelismo ................................................................................................................ 135 
Threads e processos .......................................................................................................................... 136 
Criação de threads e processos ......................................................................................................... 137 
Múltiplas threads e processos ............................................................................................................ 137 
Travas (Lock) ..................................................................................................................................... 139 
Compartilhando variáveis entre processos......................................................................................... 142 
Verificando o aprendizado ...................................................................................................................... 143 
Python como ferramenta para desenvolvimento web ................................................................... 144 
Introdução ..............................................................................................................................................144 
Frameworks Full-Stack ....................................................................................................................... 144 
Frameworks não Full-Stack ................................................................................................................ 145 
Conceitos ............................................................................................................................................... 145 
Aprimorando rotas .............................................................................................................................. 146 
Recebendo parâmetros ...................................................................................................................... 147 
Métodos HTTP ................................................................................................................................... 149 
Utilizando modelos ............................................................................................................................. 150 
Verificando o aprendizado ...................................................................................................................... 153 
Python como ferramenta para ciência de dados ........................................................................... 154 
Introdução .............................................................................................................................................. 154 
Conceitos ............................................................................................................................................... 156 
Supervisionado – regressão linear ..................................................................................................... 156 
Supervisionado ‒ classificação .......................................................................................................... 158 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 8 
 
Não supervisionado ‒ agrupamento ................................................................................................... 162 
Verificando o aprendizado ...................................................................................................................... 163 
Considerações finais .............................................................................................................................. 163 
Referências ............................................................................................................................................ 164 
Explore+ ................................................................................................................................................. 164 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 9 
 
Paradigmas de Linguagens de 
Programação em Python 
Introdução 
Desde o surgimento dos computadores, centenas de linguagens de programação vêm sendo criadas 
com o objetivo de permitir ao programador mais eficiência e conforto ao escrever seus códigos. 
Muitos são os problemas que hoje em dia são solucionados com a ajuda de softwares, escritos 
sempre em uma linguagem de programação (que por sua vez também é um software) e muitas vezes esses 
problemas demandam diferentes pensamentos computacionais em sua solução. 
A classificação das linguagens em paradigmas permite que entendamos qual é o melhor deles para 
solucionar determinado problema e, a partir daí, escolher a linguagem de programação (pertencente a esse 
paradigma) mais adequada, conforme características e especificidades do contexto em que se aplica o 
problema. 
A linguagem Python foi escolhida como instrumento para o desenvolvimento desta disciplina, pois 
além de ser multiparadigma (possibilita escrever programas em diferentes paradigmas) e de uso geral, vem 
se destacando e sendo cada vez mais utilizada entre os novos desenvolvedores por vários motivos: 
Facilidade de aprendizado; 
Boa legibilidade de código; 
Boa facilidade de escrita; 
Produtividade e confiabilidade. 
Possui, ainda, comunidade de desenvolvedores crescente e vasta biblioteca, repleta de funções, 
aplicada a diversas áreas da ciência, assim como o crescente números de frameworks desenvolvidos para 
a linguagem. 
Classificação das linguagens de programação 
Razões para estudarmos linguagens de programação 
Linguagem de programação e produtividade do programador 
Um programa de computador, ou software, é um conjunto de instruções a fim de orientar o hardware 
do computador para o que deve ser feito. O software pode ser classificado em aplicativo ou básico. 
Software aplicativo 
Ou, simplesmente, aplicativo ou app (mundo mobile), que visa oferecer ao usuário facilidades para 
realizar uma tarefa laboral ou de lazer. 
Software básico 
Compreende programas essenciais ao funcionamento do computador. O sistema operacional é o 
principal exemplo. 
Uma linguagem de programação é um software básico, que permite ao programador escrever outros 
programas de computador, seja ela um software aplicativo ou básico. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 10 
 
A codificação de um programa em uma linguagem de programação, chama-se programa-fonte, que 
ainda não pode ser entendido e executado pelo hardware do computador, pois este apenas entende a 
linguagem de máquina ou linguagem binária, na qual cada instrução é uma sequência de bits (0 ou 1). 
Uma linguagem de programação é um formalismo com um conjunto de símbolos, palavras 
reservadas, comandos, regras sintáticas e semânticas e outros recursos, que permitem especificar 
instruções de um programa. 
Atenção 
As linguagens de programação surgiram da necessidade de livrar o programador dos detalhes mais íntimos 
das máquinas em que a programação é feita, permitindo a programação em termos mais próximos ao problema, ou 
em nível mais alto. 
A produtividade de um programador ao escrever código em uma linguagem de programação está 
intimamente relacionada à facilidade de aprendizado, leitura e escrita de programas naquela linguagem, 
somada a expertise do programador no contato com a linguagem. 
Isto é, quanto mais o programador conhecer as propriedades superlativas daquela linguagem, 
melhores e mais eficientes serão os códigos escritos. 
O aspecto mais importante, mas também o mais elusivo de qualquer ferramenta, é sua influência nos hábitos 
daqueles que se treinam no seu uso. Se a ferramenta é uma linguagem de programação, essa influência é, gostemos 
ou não, uma influência em nosso hábito de pensar. Edsger W. Dijkstra 
O papel da abstração nas linguagens de programação 
Abstração é o processo de identificação das qualidades e/ou propriedades relevantes para o contexto 
que está sendo analisado e desprezando o que seja irrelevante. Um modelo é uma abstração da realidade. 
Um programa de computador é um modelo, pois representa a solução de um problema em termos 
algorítmicos. Assim sendo, a abstração permeia toda a atividade de programação de computadores. 
A linguagem de máquina foi a primeira a ser criada para a prática de programação. Trata-se da 
linguagem nativa do computador, a única que ele, de fato, compreende. Uma linguagem muito complicada 
para ser entendida pelas pessoas, em que um comando que soma 2 números, é formado por uma sequência 
de 1 e 0, muito difícil de ser memorizada, usada e, mais ainda, de ser entendida por terceiros. 
As primeiras linguagens de programação, porém, não reconheciam o papel crucial que a abstração 
desempenha na programação. Por exemplo, no início da década de 1950, o único mecanismo de abstração 
fornecido pela linguagem de montagem, ou Assembly, em relação às linguagens de máquina eram os nomes 
simbólicos. 
Você sabia 
O programador podia empregar termos relativamente autoexplicativos (nomes simbólicos) para nomear 
códigos de operação (ADD = soma,SUB = subtração, M = multiplicação e DIV = divisão) e posições de memória. A 
linguagem de montagem (Assembly) melhorou a vida do programador, porém obrigava-o a escrever 1 linha de código 
para cada instrução que a máquina deve executar, forçando-o a pensar como se fosse uma máquina. 
Um pouco mais adiante, visando a aumentar o poder de abstração das linguagens de forma a permitir 
uma melhor performance dos programadores, surgem as linguagens de alto nível, próximas à linguagem 
humana e mais distantes das linguagens Assembly e de máquina. 
A tabela, a seguir, exibe, à esquerda, um programa-fonte, escrito numa linguagem de alto nível, a 
linguagem Python. Ao centro, temos o código equivalente na linguagem Assembly para o sistema 
operacional Linux e, à direita, o respectivo código na linguagem de máquina, de um determinado 
processador. Observe: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 11 
 
 
Fonte: Estácio de Sá 
A imagem abaixo ilustra o conceito de abstração, em que a partir da linguagem de máquina, cria-se 
camadas (de abstração) para facilitar a vida do programador. 
 
Fonte: Estácio de Sá 
Nível 1 
É representado pelo hardware, conjunto de circuitos eletrônicos. 
Nível 2 
É representado pela linguagem de máquina (1 e 0), única que o hardware entende. 
Nível 3 
É representado pela linguagem Assembly (mneumônicos). 
Nível 4 
É representado pelas linguagens de alto nível, próximas à língua do usuário e distantes da 
linguagem computacional. Python e Java são linguagens de programação representativas da classe 
LP de alto nível (LP = Linguagem de Programação). 
Por que estudar linguagens de programação? 
O estudante e/ou programador que se dispuser a gastar seu tempo aprendendo linguagens de programação 
terá as seguintes vantagens: 
Maior capacidade de desenvolver soluções em termos de programas — compreender bem os conceitos de 
uma LP pode aumentar a habilidade dos programadores para pensar e estruturar a solução de um problema. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 12 
 
Maior habilidade em programar numa linguagem, conhecendo melhor suas funcionalidades e implementações, 
ajuda para que o programador possa construir programas melhores e mais eficientes. Por exemplo, conhecendo como 
as LPs são implementadas, podemos entender melhor o contexto e decidir entre usar ou não a recursividade, que se 
mostra menos eficiente que soluções iterativas. 
Maiores chances de acerto na escolha da linguagem mais adequada ao tipo de problema em questão, quando 
se conhece os recursos e como a linguagem os implementa. Por exemplo, saber que a linguagem C não verifica, 
dinamicamente, os índices de acesso a posições de vetores pode ser decisivo para sua escolha em soluções que usem 
frequentemente acessos a vetores. 
Maior habilidade para aprender novas linguagens. Quem domina os conceitos da orientação a objeto, tem mais 
aptidão para aprender Python, C++, C# e Java. 
Amplo conhecimento dos recursos da LP reduz as limitações na programação. 
Maior probabilidade para projetar novas LP, aos que se interessarem por esse caminho profissional: participar 
de projetos de criação de linguagens de programação. 
Aumento da capacidade dos programadores em expressar ideias. Em geral, um programador tem expertise 
em poucas variedades de linguagens de programação, dependendo do seu nicho de trabalho. Isso, de certa forma, 
limita sua capacidade de pensar, pois ele fica restrito pelas estruturas de dados e controle que a(s) linguagem(ns) de 
seu dia a dia permitem. Conhecer uma variedade maior de recursos das linguagens de programação pode reduzir tais 
limitações, levando, ainda, os programadores a aumentar a diversidade de seus processos mentais. 
Quanto maior for o leque de linguagens que um programador dominar e praticar, maiores as chances de 
conhecer e fazer uso das propriedades superlativas da(s) linguagem(ns) em questão. 
Classificação das linguagens de programação 
Ao longo dos anos, os autores têm criado diferentes classificações para as linguagens de 
programação, usando critérios diferenciados e agrupando-as sob diferentes perspectivas. 
Veremos a seguir as classificações das linguagens por nível, por gerações e por paradigmas. 
Classificação por nível 
A classificação por nível considera a proximidade da linguagem de programação com as 
características da arquitetura do computador ou com a comunicação com o homem. 
Linguagem de baixo nível 
São linguagens que se aproximam da linguagem de máquina, além da própria, que se comunicam 
diretamente com os componentes de hardware, como processador, memória e registradores. As linguagens 
de baixo nível estão relacionadas à arquitetura de um computador. 
São linguagens escritas usando o conjunto de instruções do respectivo processador. Ou seja, cada 
processador diferente (ou família de processador, como os I3, I5 e I7 da Intel) tem um conjunto de instruções 
específicos (instructions set). 
Abaixo, a imagem ilustra a representação de uma instrução em linguagem de máquina ou binária de 
um processador específico. A instrução tem palavras (unidade executada pelo processador) de 16 bits, 
sendo 4 bits para representar a instrução (código da instrução), 6 bits para representar cada operando. 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 13 
 
 
Imagine, agora, uma sequência de 0 e 1 para que possamos dizer ao processador cada ação que 
deve ser realizada conforme ilustrado abaixo. 
0001001010001111 
1010010001000010 
0010101110110111 
0101010000000111 
Era de fato muito complexa a programação na linguagem de máquina, a linguagem nativa dos 
processadores. 
Essa complexidade motivou o desenvolvimento da linguagem Assembly, que deixava de ser a 
linguagem nativa dos processadores, mas usava das instruções reais dos processadores. Assim, a instrução 
na linguagem Assembly precisa ser convertida para o código equivalente em linguagem de máquina. 
Exemplo 
As três linhas de código na linguagem Assembly, abaixo, que move o numeral 2 para o registrador AX (linha 
1), move o numeral 1 para o registrador BX (linha 2) e soma o conteúdo dos 2 registradores (linha 3). 
MOV AX, 0002 
MOV BX, 0001 
ADD AX, BX 
Não chega a ser o ideal em termos de uma linguagem, que é ainda próxima da máquina, mas 
já foi um grande avanço em relação à memorização da sequência de 0 e 1 de uma instrução de 
máquina. 
Linguagens de baixo nível estão distantes da língua humana (escrita). 
Linguagem de alto nível 
No outro extremo das linguagens de baixo nível, estão as linguagens de alto nível, na medida em 
que se afastam da linguagem das máquinas e se aproximam da linguagem humana (no caso, a linguagem 
escrita e a grande maioria em Inglês). 
Você sabia 
Quem programa em uma linguagem de alto nível não precisa conhecer características dos componentes do 
hardware (processador, instruções e registradores). Isso é abstraído no pensamento computacional. 
As instruções das linguagens de alto nível são bastante abstratas e não estão relacionadas à 
arquitetura do computador diretamente. As principais linguagens são: 
ASP, C, C++, C#, Pascal, Delphi, Java, Javascript, Lua, MATLAB, PHP e Ruby, dentre outras. 
Exemplo 
Abaixo, o mesmo código expresso acima, escrito em Assembly, porém usando variáveis, como abstração do 
armazenamento e codificado na linguagem Python. 
def main(): 
 num1 = 2 
 num2 = 1 
 soma = num1 + num2 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 14 
 
Abaixo, o mesmo código na linguagem C: 
int num1, num2, soma; 
int main() 
{ 
 num1=2; 
 num1=1; 
 soma=num1+num2; 
} 
Cada comando de uma linguagem de alto nível precisa ser convertido e equivalerá a mais de uma 
instrução primária do hardware. Isso significa que, numa linguagem de alto nível, o programador precisaescrever menos código para realizar as mesmas ações, além de outras vantagens, aumentando 
consideravelmente a sua eficiência ao programar. 
Saiba mais 
Há uma curiosidade: C e C++ são classificados por alguns autores como linguagem de médio nível, na medida 
que estão próximas da linguagem humana (linguagem de alto nível), mas também estão próximas da máquina 
(linguagem de baixo nível), pois possuem instruções que acessam diretamente memória e registradores. Inicialmente, 
a linguagem C foi criada para desenvolver o sistema operacional UNIX, que até então era escrito em Assembly. 
 
Outro dado que merece ser comentado é que algumas pessoas consideram a existência de linguagens de 
altíssimo nível, como Python, Ruby e Elixir, por serem linguagens com uma enorme biblioteca de funções e que 
permitem a programação para iniciantes sem muito esforço de aprendizado. 
Classificação por gerações 
Outra forma de classificar as linguagens, amplamente difundida, é por gerações. Não há um 
consenso sobre as gerações, alguns consideram 5, outros 6. A cada geração, novos recursos facilitadores 
são embutidos nas respectivas linguagens. 
 
Fonte: Estácio de Sá 
Veja um pouco mais sobre as gerações: 
Linguagens de 1ª geração (linguagem de máquina) 
A 1ª geração de linguagens é representa pela linguagem de máquina, nativa dos processadores. 
Linguagens de 2ª geração (linguagem de montagem – assembly) 
As linguagens de segunda geração são denominadas Assembly e são traduzidas para a linguagem 
de máquina por um programa especial (montador), chamado Assembler. A partir dessa geração, toda 
linguagem vai precisar de um processo de conversão do código nela escrito, para o código em linguagem 
de máquina. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 15 
 
Acompanhe o exemplo abaixo para uma CPU abstrata. Considere a seguinte sequência de 3 
instruções em linguagem Assembly: 
 
Fonte: Estácio de Sá 
Em linguagem de máquina, depois de traduzidas pelo Assembler, as instruções poderiam ser 
representadas pelas seguintes sequências de palavras binárias: 
 
Fonte: Estácio de Sá 
Houve um aumento significativo no nível de abstração, mas parte da dificuldade permanece, pois o 
programador, além de necessitar memorizar os mneumônicos, precisa conhecer a arquitetura do 
computador como forma de endereçamento dos registradores e memória, além de outros aspectos. 
Linguagens de 3ª geração (linguagens procedurais) 
São as, também, linguagens de alto nível, de aplicação geral, em que uma única instrução em uma 
linguagem próxima a do homem pode corresponder a mais de uma instrução em linguagem de máquina. 
Caracterizam-se pelo suporte a variáveis do tipo simples (caractere, inteiro, real e lógico) e 
estruturados (matrizes, vetores, registros), comandos condicionais, comando de iteração e programação 
modular (funções e procedimentos), estando alinhadas à programação estruturada. 
O processo de conversão para a linguagem de máquina ficou mais complexo e ficaram a cargo dos 
interpretadores e tradutores. As primeiras linguagens de 3ª geração que foram apresentadas ao mercado 
são: Fortran, BASIC, COBOL, C, PASCAL, C, dentre outras. 
Esta geração de linguagens apresenta as seguintes propriedades em comum: 
Armazenar tipos de dados estaticamente: simples, estruturados e enumerados. 
Alocar memória dinamicamente, através de ponteiros, que são posições de memória cujo conteúdo 
é outra posição de memória. 
Disponibilizar: estruturas de controle sequencial, condicional, repetição e desvio incondicional. 
Permitir a programação modular, com uso de parâmetros. 
Operadores: relacionais, lógicos e aritméticos. 
Ênfase em simplicidade e eficiência. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 16 
 
Linguagens de 4ª geração (linguagens aplicativas) 
São, também, linguagens de alto nível, com aplicação e objetivos bem específicos. 
Enquanto as linguagens de 3ª geração são procedurais, ou seja, especifica-se passo a passo a 
solução do problema, as de 4ª geração são não procedurais. O programador especifica o que deseja fazer 
e não como deve ser feito. 
O melhor exemplo de linguagens de 4ª geração é a SQL (Structured Query Language), utilizada para 
consulta à manipulação de banco de dados. PostScript e MATLAB são outros dois exemplos de linguagens 
de 4ª geração. 
Linguagens de 5ª geração (voltadas à inteligência artificial) 
São linguagens declarativas e não algorítmicas. Exemplos: Lisp e Prolog. As linguagens de 5ª 
geração são usadas para desenvolvimento de sistemas especialistas (área da IA), de sistemas de 
reconhecimento de voz e machine learning. 
A imagem a seguir ilustra as características de cada geração. 
 
Fonte: Estácio de Sá 
Verificando o aprendizado 
1. Avalie as assertivas sobre as linguagens de programação: 
I. Linguagem Assembly é a nativa dos computadores. 
II. Uma Linguagem deve ser compatível única e exclusivamente com o hardware a que se propôs a atender. 
III. A abstração traz facilidades ao programador que cada vez menos precisa conhecer o ambiente onde a 
linguagem opera (composto por sistema operacional e hardware). 
IV. Um comando em uma linguagem de alto nível faz mais que uma operação primária do hardware. 
Com base em sua análise, marque a opção que apresenta apenas as assertivas corretas. 
A. I, II, III e IV 
B. III e IV apenas 
C. III apenas 
D. II e IV apenas 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 17 
 
2. Relacione a coluna A, na qual temos as gerações das linguagens de programação com a coluna B, em que 
temos as características das gerações de linguagens: 
 
A – Gerações B – Características das gerações 
1 – 1ª geração a – Linguagem de alto nível 
2 – 3ª geração b – Linguagem Assembly 
3 – 4ª geração c – Linguagem de máquina 
4 – 2ª geração d – Linguagens não procedimentais 
 
Com base em sua análise, marque a opção que relaciona corretamente as duas colunas A e B: 
A. 1-c, 2-a, 3-d, 4-b 
B. 1-a, 2-c, 3-d, 4-b 
C. 1-d, 2-b, 3-a, 4-c 
D. 1-b, 2-c, 3-d, 4-a 
Critérios de avaliação de linguagens de programação 
Considerando as diversas linguagens de programação existentes hoje no mercado, atendendo a 
propósito comuns, vamos destacar neste módulo os domínios da programação, que são seis: 
1. Aplicações científicas 
2. Aplicações comerciais 
3. Aplicações com Inteligência Artificial 
4. Programação de sistemas 
5. Programação para web 
6. Programação mobile 
Na sequência, apresentaremos critérios que podem ser usados para avaliação de linguagens de 
programação, claro, dentro do mesmo domínio de programação. 
Domínios da programação 
O computador tem sido usado para diversos fins, na ciência, nas forças armadas, nas empresas 
públicas e privadas, pelos profissionais liberais, pelas pessoas em seus lazeres e onde mais possa ser 
aplicado. Seu uso vai desde controlar robôs que fazem a montagem de automóveis em suas linhas de 
montagem até jogos digitais. Em função desse uso adverso, surgiram linguagens de programação com 
diferentes objetivos. A seguir, discutiremos as principais áreas e as respectivas linguagens de programação 
em destaque. 
Aplicações científicas (máquinas de calcular com alta precisão) 
O primeiro computador, o ENIAC, foi desenvolvido por 3 anos e ficou pronto no ano de 1946. Sua 
principal finalidade eram cálculos balísticos. Os computadores seguintes, nas décadas de 1940 e 1950, 
também focaram em cálculos científicos complexos. 
As linguagens de programação nessa época eram a linguagem de máquina e Assembly. Na década 
de 1960 surgem as primeiras linguagens de programação de alto nível, com destaque para Fortran (iniciais 
de FORmula TRANslator) e posteriormente para ALGOL60. As principais características dessas linguagens 
eram: 
Estruturas de dados simples. 
Alto volume de cálculos com aritmética de ponto flutuante (precisão). 
Preocupaçãocom a eficiência, pois sucederam a linguagem Assembly. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 18 
 
Aplicações comerciais 
A segunda onda de aplicativos foi para suprir as demandas das empresas a partir de meados da 
década de 1950. Em 1960, surge a linguagem que seria o ícone das aplicações comerciais de computadores 
de grande porte, naquele momento, o COBOL. As linguagens de programação que apoiaram o crescimento 
das aplicações comerciais têm como características: 
Facilidade para produzir relatórios, fundamentais nos controles das operações contábeis, 
bancárias, estoque e financeiras (primeiros focos da época). 
Precisão com números decimais e ponto flutuante, para representar as altas cifras das grandes 
empresas, as primeiras a investirem nessas aplicações. 
Capacidade de especificar operações aritméticas comerciais. 
Cabe destacar que as linguagens destinadas a aplicações comerciais ganham força com a 
microcomputação a partir dos anos 1980, levando as aplicações comerciais aos médios e pequenos 
empresários. 
Aplicações com inteligência artificial 
As linguagens que sustentam o desenvolvimento de aplicações apoiadas na Inteligência Artificial (IA) 
ganham força nos dias de hoje. 
A grande ruptura no pensamento computacional é que as linguagens que apoiam a IA usam a 
computação simbólica e não numérica, como a maioria das linguagens da época. Em 1959, surge a 
linguagem Lisp, primeira linguagem projetada para apoio à computação simbólica, primeira referência da 
computação funcional. Prolog, criada em 1977, foi a primeira linguagem para apoio da computação lógica, 
essência dos sistemas especialistas (sistemas que usam IA para simular o comportamento humano). 
Programação de sistemas 
A programação de sistemas cabe a linguagens de programação que tenham comandos e estruturas 
para acessar, diretamente, o hardware. Tais linguagens são usadas para desenvolver softwares básicos, 
como sistemas operacionais, tradutores e interpretadores de linguagens de programação. Antes de surgir a 
linguagem C, usada para desenvolver o sistema operacional Linux, Assembly era a linguagem usada para 
esse fim. A linguagem C++ também é usada com essa finalidade. 
Programação para web 
Com o crescimento da internet e tecnologias adjacentes, o uso dos sistemas se desloca do ambiente 
desktop (domínio dos anos 1980 e 1990) para o ambiente Web. 
No contexto de programação para Web, temos 2 diferentes ambientes de desenvolvimento: a 
camada de apresentação, que roda no navegador (lado cliente) e a camada de lógica do negócio, que roda 
nos servidores web (lado servidor), juntamente com a camada de persistência, considerando o modelo de 
desenvolvimento em 3 camadas (apresentação, lógica do negócio e persistência de dados). 
Para a camada de apresentação, usa-se as linguagens HTML (linguagem de marcação) e CSS 
(usada em conjunto com HTML para definir a apresentação da página web), além de JavaScript 
(programação de scripts), no lado cliente (navegadores). 
Para o desenvolvimento das camadas de lógica do negócio, as principais LP são: C#, PHP, ASP, 
.NET, Java, Ruby e Python. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 19 
 
Programação mobile 
Considerando que hoje em dia, grande parte da população, no Brasil e no Mundo, tem acesso à 
internet pelo celular, cresceu vertiginosamente a quantidade de apps (aplicativos) para uso de aplicações 
via celular. Os apps, na verdade, são interfaces que rodam no lado cliente. 
As principais (não todas) linguagens que apoiam o desenvolvimento de apps para o mundo mobile, 
oficialmente indicadas por seus fabricantes, são: 
Android: Java e Kotlin. 
iOS: Swift (oficial da Apple) e Objective-C (código nativo para iOS). 
Windows: C#, Visual Basic (VB), C++, HTML, CSS, JavaScript e Java. 
O desenvolvimento de APP para iOS é baseado numa IDE chamada Xcode que permite o 
desenvolvimento de APP em várias linguagens, como: C, C++, Java e Python, mas oficialmente orienta o 
Swift e Objective-C. 
A Google, por sua vez, tem por base o Android SDK, orienta a usar as linguagens Kotlin, Java e C++, 
mas as linguagens Python, Shell script, Basic4Android, LiveCode (para iOS e Windows também), App 
Inventor (não necessita conhecer programação) e Unity (motor para games) e GO, também são usadas para 
desenvolver app para Android. 
No contexto de desenvolvimento de APP para Windows, foi lançado no Windows 8.1 e atualizado 
para atender também ao Windows 10, o App Studio, que permite a qualquer pessoa criar em poucos passos 
um app Windows e publicá-lo na loja. 
Importante destacar que hoje existem plataformas de desenvolvimento mobile conectadas a nuvem 
que fomentam o desenvolvimento de apps nativos para iOS, Android e Windows. 
Avaliação de linguagens de programação 
Segundo Sebesta (2018) são quatro grandes critérios para avaliação das linguagens de 
programação, dentro de um mesmo domínio de programação. Cada critério é influenciado por algumas 
características da linguagem. 
Legibilidade 
Um dos critérios mais relevantes é a “facilidade com que os programas podem ser lidos e 
entendidos” pelas pessoas que não necessariamente participaram do desenvolvimento. 
Facilidade de escrita 
O quão facilmente uma linguagem pode ser usada para desenvolver programas para o domínio do 
problema escolhido. 
Confiabilidade 
Um programa é dito confiável se ele se comporta conforme a sua especificação, repetidas vezes. 
Custo 
O custo final de uma linguagem de programação é em função de muitas de suas propriedades e 
características. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 20 
 
A tabela a seguir exibe as características da linguagem que influenciam cada um dos três principais 
fatores de avaliação de linguagens. 
Critérios 
Características Legibilidade Facilidade escrita Confiabilidade 
Simplicidade 
 
Ortogonalidade 
 
Estruturas de controle 
 
Tipos de dados 
 
Projeto de sintaxe 
 
Suporte para abstração 
 
Expressividade 
 
Verificação de tipos 
 
Tratamento de exceções 
 
Aliasing 
 
Características x Critérios de Avaliação de LPs 
Legibilidade 
Um dos critérios mais relevantes para avaliar uma linguagem de programação diz respeito à 
capacidade com que os programas podem ser lidos e entendidos pela sintaxe e construção da linguagem, 
sem considerar as possíveis influências da má programação. 
As características que influenciam a legibilidade de uma linguagem de programação são: 
Simplicidade 
Quanto mais simples for uma linguagem, melhor será a legibilidade do código por ela produzido. Uma 
linguagem com número elevado de construções básicas é mais difícil de ser aprendida do que uma que 
tenha poucas. Tende a ser subutilizada. 
Uma segunda característica que afeta negativamente a legibilidade é a multiplicidade de recursos. 
Por exemplo, em Python, o programador pode incrementar uma variável, de duas formas distintas: 
cont= cont + 1; 
cont +=1. 
Nas linguagens C e Java, ainda podemos usar para incrementar variáveis as seguintes estruturas: 
++cont e cont++. 
Muita simplicidade pode tornar menos legíveis os códigos escritos. Na linguagem Assembly, a 
maioria das sentenças são simples, porém não são altamente legíveis devido à ausência de estruturas de 
controle. 
Uma terceira característica que afeta negativamente a legibilidade é a sobrecarga de operadores, 
como por exemplo o “+”, usado para somar inteiros, reais, concatenar cadeias de caracteres (strings), somar 
vetores, dentre outras construções permitidas pela linguagem. 
Ortogonalidade 
A ortogonalidade de uma linguagem refere-se a um conjunto relativamente pequeno de construções 
primitivas que pode ser combinado em um número, também, pequeno de maneiras para construir as 
estruturas de controle e de dados de uma linguagem de programação. 
Em outras palavras: possibilidade decombinar, entre si, sem restrições, as construções básicas da 
linguagem para construir estruturas de dados e de controle. 
Boa ortogonalidade: Permitir, por exemplo, que haja um vetor, cujos elementos sejam do tipo 
registro (estrutura heterogênea). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 21 
 
Má ortogonalidade: Não permitir que um vetor seja passado como argumento para uma rotina 
(procedimento ou função). Ou que uma função não possa retornar um vetor. 
Uma linguagem ortogonal tende a ser mais fácil de aprender e tem menos exceções. 
A falta de ortogonalidade leva a muitas exceções às regras da linguagem e ao excesso, o contrário 
(menos exceções às regras). Menos exceções implicam um maior grau de regularidade no projeto da 
linguagem, tornando-a mais fácil de ler, entender e aprender. 
Instruções de controle 
Instruções como Goto (desvio incondicional) limitam a legibilidade dos programas, pois essa 
instrução pode levar o controle do código a qualquer ponto do programa, limitando o entendimento e, 
consequentemente, a legibilidade do código escrito na linguagem. As linguagens modernas não 
implementam desvio incondicional, assim sendo, o projeto de estruturas de controle é menos relevante na 
legibilidade do que anos atrás, quando surgiram as primeiras linguagens de alto nível. 
Tipos e estruturas de dados 
A facilidade oferecida pela linguagem para definir tipos e estruturas de dados é outra propriedade 
que aumenta a legibilidade do código escrito. Por exemplo, uma linguagem que permita definir registros e 
vetores, mas não permite que um vetor tenha registros como seus elementos, terá a legibilidade afetada. 
A linguagem C não possui o tipo de dado lógico ou booleano. Muitas vezes, usa-se variáveis inteiras, 
permitindo apenas que receba os valores 0 e 1 para conteúdo, simulando o tipo booleano. Por exemplo, 
para localizar um elemento em uma das posições de um vetor, usa-se uma variável lógica se a linguagem 
permitir e, assim, teríamos a instrução “achou=false” em determinado trecho de código. Em outra linguagem 
que não permita o tipo de dado lógico, a instrução poderia ser “achou=0”, em que achou seria uma variável 
inteira. Qual das duas sentenças é mais clara a quem lê o código? A primeira, não é? “achou=false”. 
Sintaxe 
A sintaxe tem efeito sobre a legibilidade. Um exemplo é a restrição do tamanho (quantidade de 
caracteres) para um identificador (tipo, variável, constante, rotina – procedimento e função), impedindo que 
recebam nomes significativos sobre sua utilidade. Na linguagem Fortran, o nome do identificador pode ser 
até 6 caracteres. 
Outra propriedade de sintaxe que afeta a legibilidade é o uso de palavras reservadas da linguagem. 
Por exemplo, em Pascal, os blocos de instrução são iniciados e encerrados com BEGIN-END, 
respectivamente. A linguagem C usa chaves para iniciar e encerrar blocos de instruções. Já a linguagem 
Python usa a endentação obrigatória para marcar blocos de comandos, aumentando a legibilidade, 
naturalmente. 
Facilidade de escrita (redigibilidade) 
A facilidade de escrita é a medida do quão fácil a linguagem permite criar programas para um domínio 
da aplicação. 
A maioria das características que afeta a legibilidade também afeta a facilidade de escrita, pois se a 
escrita do código não flui, haverá dificuldade para quem for ler o código. 
As características que influenciam na facilidade de escrita são: 
Simplicidade e ortogonalidade 
Quanto mais simples e ortogonal for a linguagem, melhor sua facilidade para escrever programas. O 
ideal são linguagens com poucas construções primitivas. 
Imagina que uma linguagem de programação possui grande número de construções. Alguns 
programadores podem não usar todas, deixando de lado, eventualmente, as mais eficientes e elegantes. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 22 
 
Expressividade 
Uma linguagem de programação com boa expressividade contribui para o aumento da facilidade de 
escrita dos códigos. 
Assembly: Baixa expressividade. 
Pascal e C, boa expressividade: Ricas estruturas de controle. Exemplo: o comando FOR mais 
adequado que WHILE e REPEAT para representar lações com número fixo de vezes. Da mesma 
forma que o C, em que o FOR é mais indicado que o WHILE e DO-WHILE. Na linguagem Python, 
ocorre o mesmo entre os comandos FOR e WHILE. 
Na linguagem C, temos construções diversas para incremento de variável: i++ é mais simples e 
conveniente de usar do que i=i+1, sendo i, uma variável inteira. 
Uma linguagem expressiva possibilita escrever linhas de código de uma forma mais conveniente ao 
invés de deselegante. 
Suporte para a abstração 
O grau de abstração em uma linguagem é uma propriedade fundamental para aumentar a facilidade 
de escrita. Abstração pode ser de: 
Processos, como o conceito de subprograma. 
Dados, como uma árvore ou lista simplesmente encadeada. 
Confiabilidade 
Dizemos que um programa é confiável se ele se comportar conforme sua especificação, sob todas 
as condições, todas as vezes em que for executado. 
Abaixo, alguns recursos das linguagens que exercem efeito sobre a confiabilidade de programas. 
Verificação de tipos 
Significa verificar, em tempo de compilação ou execução, se existem erros de tipo. Por exemplo, 
atribuir um valor booleano a uma variável do tipo inteira, vai resultar em erro. As linguagens fortemente 
tipadas, em tempo de compilação, como Python e Java, tendem a ser mais confiáveis, pois apenas valores 
restritos aos tipos de dados declarados poderão ser atribuídos e diminuem os erros em tempo de execução. 
Linguagens, como C, em que não é verificado se o tipo de dado do argumento é compatível com o parâmetro, 
em tempo de compilação, podem gerar erros durante a execução, afetando a confiabilidade. A verificação 
de tipos em tempo de compilação é desejável, já em tempo de execução é dispendiosa (mais lenta e requer 
mais memória), e mais flexível (menos tipada). 
Tratamento de exceção 
O tratamento de exceção em uma linguagem de programação garante a correta execução, 
aumentando a confiabilidade. As linguagens Python, C++ e Java possuem boa capacidade de tratar 
exceções, ao contrário da linguagem C. A linguagem deve permitir a identificação de eventos indesejáveis 
(estouro de memória, busca de elemento inexistente, overflow etc.) e especificar respostas adequadas a 
cada evento. O comportamento do programa torna-se previsível com a possibilidade de tratamento das 
exceções, o que tende a aumentar a confiabilidade do código escrito na linguagem de programação. 
Aliasing (apelidos) 
Aliasing é o fato de ter dois ou mais nomes, referenciando a mesma célula de memória, o que é um 
recurso perigoso e afeta a confiabilidade. Restringir Aliasing é prover confiabilidade aos programas. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 23 
 
Legibilidade e facilidade de escrita 
Ambos influenciam a confiabilidade. A legibilidade afeta tanto na fase de codificação como na fase 
de manutenção. Programas de difícil leitura são difíceis de serem escritos também. 
Uma linguagem com boa legibilidade e facilidade de escrita gera códigos claros, que tendem a 
aumentar a confiabilidade. 
Custo 
O custo de uma linguagem de programação varia em função das seguintes despesas: de 
treinamento, de escrita do programa, do compilador, de execução do programa, de implementação da 
linguagem e o de manutenção do código. 
Custo de Características 
Treinamento 
Custo de Treinamento para programadores varia em função da expertise do programador, simplicidade e 
ortogonalidade da linguagem; 
F (simplicidade de escrita, ortogonalidade, experiência do programador). 
Escrever programa 
Custo para escrever programas na linguagem varia em função da facilidade de escrita. 
F(Facilidade de escrita). 
Compilar o programa 
Esse custo varia em função do custo de aquisição do compilador,hoje minimizado, em linguagens open source, 
como é o caso do Python. 
F (custo de aquisição do compilador). 
Executar o programa 
Custo para executar programas, varia em função do projeto da linguagem. 
F (Projeto da linguagem). 
Implementar a linguagem 
A popularidade da LP vai depender de um econômico sistema de implementação. Por exemplo, Python e Java 
possuem compiladores e interpretadores gratuitos. 
Confiabilidade 
O custo da má confiabilidade: se um sistema crítico falhar, o custo será elevado. Exemplos: sistema de controle 
de consumo de água e sistemas de usina nuclear. 
Manutenção 
Custo de manutenção: depende de vários fatores, mas principalmente da legibilidade, já que a tendência é que a 
manutenção seja dada por pessoas que não participaram do desenvolvimento do software. 
Os custos em treinamento e de escrever o programa podem ser minimizados se a linguagem oferecer 
bom ambiente de programação. 
Python é uma linguagem com alta legibilidade, facilidade de escrita, além de confiável. Seu 
custo não é elevado, pois além de ser open source, é fácil de aprender. 
Atenção 
Existem outros critérios, como por exemplo a portabilidade ou a capacidade que os programas têm de rodarem 
em ambientes diferentes (sistema operacional e hardware), o que é altamente desejável. A reusabilidade, ou seja, o 
quanto um código pode ser reutilizado em outros programas ou sistemas aumenta o nível de produtividade da 
linguagem. Além da facilidade de aprendizado, que é fortemente afetada pela legibilidade e facilidade de escrita. 
Verificando o aprendizado 
1. Dos domínios de programação apresentados na aula, quais devem considerar, necessariamente, a 
arquitetura cliente-servidor? 
A. Programação web e Mobile. 
B. Programação de sistemas e aplicações comerciais. 
C. Aplicações de Inteligência Artificial e aplicações científicas. 
D. Aplicações comerciais e programação de sistemas. 
2. Um dos critérios mais relevantes na avaliação de linguagens de programação diz respeito à facilidade com 
que os programas podem ser lidos. Estamos falando de qual critério? 
A. Legibilidade 
B. Redigibilidade 
C. Confiabilidade 
D. Custo 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 24 
 
Os paradigmas e suas características 
O agrupamento por paradigmas é outra forma de classificar as linguagens de programação. Um 
paradigma agrupa linguagens com características semelhantes que surgiram em uma mesma época. 
A imagem a seguir ilustra os cinco paradigmas nos quais as linguagens de programação são 
classificadas. Esses paradigmas são agrupados em Imperativos e Declarativos, de acordo com a forma com 
que os programas são estruturados e descritos. 
 
Fonte: Estácio de Sá 
Você também pode acompanhar mais informações sobre a classificação dos paradigmas das 
linguagens de programação assistindo ao vídeo: 
Paradigma imperativo 
O paradigma imperativo agrega três paradigmas: estruturado, orientado a objeto e concorrente, os 
quais possuem em comum o fato de especificarem passo a passo o que deve ser feito para a solução do 
problema. As linguagens do paradigma imperativo são dependentes da arquitetura do computador, pois 
especificam em seus programas como a computação é realizada. 
Vamos explicar as características de cada um dos paradigmas do subgrupo Imperativo. 
Paradigma estruturado 
Caracteriza as principais linguagens de programação da década de 1970 e 1980 que seguiram os 
princípios da programação estruturada: 
1. Não usar desvios incondicionais (Goto, característico de linguagens como BASIC e versões 
iniciais do COBOL). 
2. Desenvolver programas por refinamentos sucessivos (metodologia top down), motivando o 
desenvolvimento de rotinas (procedimentos e funções) e a visão do programa partindo do 
geral para o particular, ou seja, o programa vai sendo refinado à medida que se conhece 
melhor o problema e seus detalhes. 
3. Desenvolver programas usando três tipos de estruturas: sequenciais, condicionais e 
repetição. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 25 
 
4. Visando eficiência, o paradigma estruturado baseia-se nos princípios da arquitetura de Von 
Neumann, onde: 
a. Programas e dados residem, na memória (durante a execução). 
b. Instruções e dados trafegam da memória para CPU e vice-versa. 
c. Resultados das operações trafegam da CPU para a memória. 
As linguagens Pascal e C caracterizam bem esse paradigma. A linguagem Python, 
multiparadigma, tem o estilo básico do paradigma estruturado. 
Paradigma orientado a objetos 
Com o crescimento do tamanho do código e complexidade dos programas, o paradigma estruturado 
começou a apresentar limitações nos sistemas que passaram a ter dificuldade de manutenção e reuso de 
programas e rotinas padronizadas. 
A orientação a objetos surge como solução a esses problemas, permitindo, através de propriedades 
como abstração, encapsulamento, herança e polimorfismo, maior organização, reaproveitamento e 
extensibilidade de código e, consequentemente, programas mais fáceis de serem escritos e mantidos. 
O principal foco desse paradigma foi possibilitar o desenvolvimento mais rápido e confiável. 
As classes são abstrações que definem uma estrutura que encapsula dados (chamados de atributos) 
e um conjunto de operações possíveis de serem usados, chamados métodos. Os objetos são instâncias das 
classes. 
Exemplo 
Por exemplo, a classe ALUNO encapsula um conjunto de dados que os identifiquem: matrícula, nome, 
endereço (rua, número, complemento, bairro, estado e CEP) e um conjunto de métodos: Incluir Aluno, Matricular Aluno, 
Cancelar Matrícula, dentre outros. 
O paradigma orientado a objetos, por sua vez, usa os conceitos do paradigma estruturado na 
especificação dos comandos de métodos. Por isso, é considerado uma evolução do paradigma estruturado. 
Atenção 
Phyton, Smalltalk, C++, Java, Delphi (oriundo do Object Pascal) são linguagens que caracterizam o paradigma 
orientado a objetos. Python é orientado a objeto, pois tudo em Python é objeto, permitindo a declaração de classes 
encapsuladas, além de possibilitar herança e polimorfismo. 
Paradigma concorrente 
Caracterizado quando processos executam simultaneamente e concorrem aos recursos de hardware 
(processadores, discos e outros periféricos), características cada vez mais usuais em sistemas de 
informação. 
O paradigma concorrente pode valer-se de apenas um processador ou vários. 
Um processador 
Os processos concorrem ao uso do processador e recursos. 
Vários processadores 
Estamos caracterizando o paralelismo na medida em que podem executar em diferentes 
processadores (e de fato, ao mesmo tempo), os quais podem estar em uma mesma máquina ou 
distribuídos em mais de um computador. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 26 
 
Ada e Java são as linguagens que melhor caracterizam esse paradigma, possibilitando suporte à 
concorrência. 
Você sabia 
Ao contrário de Go, Python não foi originalmente projetada com foco em programação concorrente, muito 
menos paralela. O modo tradicional de programar concorrência em Python -- threads -- é limitado no interpretador 
padrão (CPython) por uma trava global (a GIL), que impede a execução paralela de threads escritas em Python. Isso 
significa que threads em Python são úteis apenas em aplicações I/O bound – em que o gargalo está no I/O (entrada e 
saída), como é o caso de aplicações na Internet. 
Paradigma declarativo 
Diferentemente do paradigma imperativo, no declarativo o programador diz o que o programa deve 
fazer (qual a tarefa), ao invés de descrever como o programa deve fazer. O programador declara, de forma 
abstrata, a solução do problema. 
Essas linguagens não são dependentes de determinada arquitetura de computador. As variáveis são 
incógnitas, tal qual na Matemática e não células de memória. 
O paradigma declarativo agrega os paradigmasfuncional e lógico. 
Vamos explicar as características de cada um. 
Paradigma funcional 
Abrange linguagens que operam tão somente funções que recebem um conjunto de valores e 
retornam um valor. O resultado que a função retorna é a solução do problema (foca o processo de resolução 
de problemas). 
O programa resume-se em chamadas de funções, que por sua vez podem usar outras funções. Uma 
função pode invocar outra, ou o resultado de uma função pode ser argumento para outra função. Usa-se 
também chamadas recursivas de funções. 
Naturalmente, esse paradigma gera programas menores (pouco código). 
Linguagens típicas desse paradigma são: LISP, HASKELL e ML. 
LISP é a LP funcional mais usada, especialmente em programas que usem os conceitos de 
Inteligência Artificial (sistemas especialistas, processamento de linguagem natural e representação do 
conhecimento), devido à facilidade de interpretação recursiva. 
Exemplo: O código abaixo implementa em Python uma função que calcula quantos números inteiros 
existem de 0 a n. 
def conta_numeros(n): 
 p = 0 
 for num in range(n+1): 
 if num%2 == 0: 
 p += 1 
 return p 
Abaixo, o mesmo código usando o conceito de função recursiva. Repare que a função de nome 
conta_numeros chama ela mesma em seu código (isso é a recursão). 
def conta_numeros(n): 
 if n == 0: return 1 # 0 é par 
 elif n%2 == 0: return 1 + conta_numeros(n-1) 
 else: return conta_numeros(n-1) 
Atenção 
Python não é uma linguagem funcional nativa, seria exagerado afirmar isso, porém sofreu influência desse 
paradigma ao permitir: recursividade, uso de funções anônimas, com a função lambda, dentre outros recursos, além, 
claro, de ser uma linguagem com enorme biblioteca de funções. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 27 
 
Paradigma lógico 
Um programa lógico expressa a solução da maneira como o ser humano raciocina sobre o problema: 
baseado em fatos, derivam-se conclusões e novos fatos. 
Quando um novo questionamento é feito, através de um mecanismo inteligente de inferência, deduz 
novos fatos a partir dos existentes. 
A execução dos programas escritos em linguagens de programação lógica segue, portanto, um 
mecanismo de dedução automática (máquina de inferência), sendo Prolog a linguagem do paradigma lógico 
mais conhecida. 
O paradigma lógico é usado no desenvolvimento de linguagens de acesso a banco de dados, 
sistemas especialistas (IA), tutores inteligentes etc. 
Python não tem características para implementar programas que atendam ao paradigma lógico. 
Verificando o aprendizado 
1. As linguagens de programação podem se enquadrar em um ou vários paradigmas, nos quais a linguagem 
tem uma grande flexibilidade e potencial de aproveitamento. Nesse contexto, Python é uma linguagem: 
A. Compatível apenas com o paradigma estruturado. 
B. Compatível apenas com os paradigmas estruturado e lógico. 
C. Compatível apenas com o paradigma orientado a objetos. 
D. Multiparadigma. 
 
2. Relacione a coluna A, em que temos paradigmas das linguagens de programação com a coluna B, em que 
temos as características dos paradigmas de linguagens: 
A – Paradigmas B – Características dos paradigmas 
1 – Estruturado a – Fomenta a reusabilidade pelos mecanismos de herança e polimorfismo 
2 – Orientado a objeto 
b – Desenvolver programas usando três tipos de estruturas: sequenciais, condicionais e 
repetição 
3 – Concorrente c – Lisp é a linguagem mais significativa desse paradigma 
4 – Funcional d – Processos executam simultaneamente e concorrem aos recursos de hardware 
 
Com base em sua análise, marque a opção que relaciona corretamente as duas colunas A e B: 
A. 1-b, 2-a, 3-d, 4-c 
B. 1-a, 2-c, 3-d, 4-b 
C. 1-d, 2-b, 3-a, 4-c 
D. 1-b, 2-c, 3-d, 4-a 
 
Métodos de implementação das linguagens 
Todo programa, a menos que seja escrito em linguagem de máquina, o que hoje em dia está 
totalmente fora dos propósitos, precisará ser convertido para linguagem de máquina antes de ser executado. 
Essa conversão precisa de um programa que receba o código-fonte escrito na linguagem e gere o 
respectivo código em linguagem de máquina. 
Esse programa, que fará a tradução do código-fonte em linguagem de máquina, é que vai determinar 
como os programas são implementados e como vão executar. 
Existem duas formas de realizar essa conversão: tradução e interpretação. É fundamental que se 
saiba e se entenda qual o processo de conversão usado na respectiva linguagem de programação. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 28 
 
Tradução 
Nesse processo de conversão, o programa escrito em uma linguagem de alto nível é traduzido para 
uma versão equivalente em linguagens de máquina, antes de ser executado. O processo de tradução pode 
ser executado em várias fases, que podem ser combinadas e executadas em simultaneidade. O processo 
de tradução é erroneamente chamado de compilação, que na verdade é uma de suas fases. 
As fases que compõem o tradutor, ou seja, iniciando na leitura do programa-fonte (linguagem de alto 
nível) e terminando com a geração do código executável (entendido pela máquina), são: Compilação, 
Montagem, Carga e Ligação. A imagem abaixo ilustra o processo de tradução. 
Compilador: O compilador (detalhes adiante) analisa o código-fonte e estando tudo OK, o converte 
para um código Assembly (da máquina hospedeira). 
Montador: O montador traduz o código Assembly para o código de máquina intermediário (Código-
objeto), que não é executável pelo computador. O código-objeto pode ser relocável, ou seja, 
carregado em qualquer posição de memória ou absoluto, carregado em um endereço de memória 
específico. A opção relocável é mais comum e mais vantajosa. 
Carregador: O carregador é que torna o código-objeto em relocável. 
Ligador: O Ligador liga (ou linka) o código-objeto relocável com as rotinas bibliotecas (outros 
objetos, rotinas do SO, DLLs etc.), usadas nos códigos-fontes. Essa ligação gera o código 
executável. 
 
Fonte: Estácio de Sá 
Compilador 
É o elemento central do processo de tradução, responsável pelo custo de compilação, visto no 
modulo anterior. Em função dessa relevância, muitas vezes o processo como um todo é erroneamente 
chamado de compilação, uma vez que o ambiente integrado das linguagens atuais já integra todos os 
componentes (montador, compilador, carregador e ligador) quando necessário. 
O projeto da linguagem tem no compilador a sua figura central. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 29 
 
A imagem abaixo ilustra os componentes envolvidos na compilação de um programa fonte: 
 
Fonte: Estácio de Sá 
Abaixo, vamos entender cada fase da compilação: 
Análise léxica 
Identifica os tokens (elementos da linguagem), desconsidera partes do código-fonte, como espaços 
em branco e comentários e gera a Tabela de símbolos, com todos esses tokens, que são 
identificadores de variáveis, de procedimentos, de funções, comandos, expressões etc. 
Análise sintática 
Verifica se os tokens são estruturas sintáticas (exemplos: expressões e comandos) válidas, 
aplicando as regras gramaticais definidas no projeto da linguagem. 
Análise semântica 
Verifica se as estruturas sintáticas possuem sentido. Por exemplo, verifica se um identificador de 
variável ou constante é usado adequadamente, se operandos e operadores são compatíveis. Monta 
a árvore de derivação conforme ilustrado abaixo para formação das expressões. 
 
Árvore de derivação de uma expressão. Fonte: Estácio de Sá 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 30 
 
Gerador de código intermediário, otimizador de código e gerador de código 
Em distintas fases geram o programa-alvo ou programa-objeto. 
Gerador de código intermediário, que contém toda a informação para gerar o código-objeto. 
Na imagem a seguir, o código intermediário está representadono último quadro – código em 
Assembly: 
 
Fonte: Estácio de Sá 
O otimizador tem por objetivo eliminar redundâncias do código intermediário e tornar o objeto mais 
enxuto e eficiente. 
Tratador de erros 
Em todas as fases existem erros: léxicos, sintáticos e semânticos. Um bom compilador apresenta 
uma boa tratativa de erros. 
Gerenciador da tabela de símbolos 
Mantém a tabela de símbolos atualizada a cada passo do compilador. 
 
Atenção 
As principais características dos compiladores são: 
• Gerar código-objeto mais otimizado. 
• Execução mais rápida que o processo de interpretação. 
• Traduz um mesmo comando apenas uma vez, mesmo que usado em várias partes do programa – 
tanto iterações como repetição de código. 
• Processo de correção de erros e depuração é mais demorado. 
• A programação final (código-objeto) é maior. 
• O programa-objeto gerado é dependente de plataforma — processador + SO (Sistema Operacional) 
— necessitando de um compilador diferente para cada família de processadores/sistema operacional. 
 
Interpretação 
A imagem abaixo ilustra o simples processo de Interpretação: 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 31 
 
Na conversão por interpretação, cada comando do programa-fonte é traduzido e executado (um a 
um) imediatamente. O interpretador traduz um comando de cada vez e chama uma rotina para completar a 
sua execução. 
O interpretador é um programa que executa repetidamente a seguinte sequência: 
1. Obter a próxima instrução do código-fonte. 
2. Interpretar a instrução (conversão para comandos em linguagem de máquina). 
3. Executar a instrução. 
Perceba que o procedimento, acima descrito, é bastante similar àquele executado por computadores 
que implementam a máquina de Von Neumann, na execução de uma instrução, conforme a seguir: 
• Obter a próxima instrução. 
• CI → endereço da próxima instrução. CI = contador de instruções. 
• RI → instrução a ser executada. RI = registrador de instruções. 
• Decodificar a instrução. 
• Executar a instrução. 
Principais características do interpretador 
Dentre as principais características do interpretador, podemos citar: 
• Atua a cada vez que o programa precisa ser executado. 
• Não produz programa-objeto persistente. 
• Não traduz instruções que nunca são executadas. 
• O resultado da conversão é instantâneo: resultado da execução do comando ou exibição de 
erro – interpretador puro. 
• Útil ao processo de depuração de código devido a mensagens de erros em tempo de 
execução (tanto análise sintática como semântica). 
• Execução mais lenta do que outros processos de tradução (compilação), pois toda vez que 
o mesmo programa é executado, os mesmos passos de interpretação são executados. 
• Consome menos memória. 
• O Código-fonte é portátil. 
o Não é gerado um código de máquina. 
o Pode executar o comando em alto nível diretamente ou gerar um código 
intermediário, que neste caso é interpretado por uma máquina virtual (VM). – 
Interpretador híbrido. 
o Se a máquina virtual foi desenvolvida para diferentes plataformas, temos a 
portabilidade do código-fonte. Este é o caso da linguagem Java. 
Tradução x interpretação 
 
 Vantagens Desvantagens 
Tradutores 
1. Execução mais rápida 
2. Permite estruturas de programas mais complexas. 
3. Permite a otimização de código. 
1. Várias etapas de conversão. 
2. Programação final é maior, necessitando de mais 
memória para sua execução. 
3. Processo de correção de erros e depuração é mais 
demorado. 
Interpretadores 
1. Depuração mais simples. 
2. Consome menos memória. 
3. Resultado imediato do programa (ou parte dele). 
1. Execução do programa é mais lenta. 
2. Estruturas de dados demasiado simples. 
3. Necessário fornecer o código fonte ao utilizador. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 32 
 
Sistemas híbridos 
O processo híbrido de implementação de uma linguagem de programação combina a execução 
rápida dos tradutores (compiladores) com a portabilidade dos interpretadores. O segredo é a geração de um 
código intermediário mais facilmente interpretável, porém não preso a uma plataforma (SO/Hardware). 
Esse código intermediário não é específico para uma plataforma, possibilitando aos programas já 
compilados para esse código serem portados em diferentes plataformas, sem alterar e nem fazer nada. Para 
cada plataforma desejada devemos ter um interpretador desse código. 
Duas importantes linguagens implementaram essa solução, com diferentes formas usando 
máquinas virtuais: Python e Java. 
Sistema de implementação de Python 
Python usa um sistema híbrido, uma combinação de interpretador e tradutor (compilador). O 
compilador converte o código-fonte Python em um código intermediário, que roda numa máquina virtual, a 
PVM (Python Virtual Machine). 
Comentário 
Curioso saber que o código Python pode ser traduzido em Bytecode Java usando a implementação Jython. 
O interpretador converte para código de máquina, em tempo de execução. O compilador traduz o 
programa inteiro em código de máquina e o executa, gerando um arquivo que pode ser executado. O 
compilador gera um relatório de erros e o interpretador interrompe o processo na medida em que localiza 
um erro. 
CPython é uma implementação da linguagem Python, um pacote com um compilador e um 
interpretador Python (Máquina Virtual Python), além de outras ferramentas para programar em Python. 
Verificando o aprendizado 
1. Como se chamam os dois processos de conversão de linguagens de alto nível em linguagens inteligíveis 
pelo computador? 
A. Tradução e interpretação. 
B. Compilação e interpretação. 
C. Análise sintática e análise léxica. 
D. Compilação e montagem. 
 
2. Avalie as assertivas a seguir: 
I. O compilador analisa o código-fonte e o converte para um executável. 
II. O montador traduz o código Assembly para o código de máquina intermediário (código objeto), que é 
executável pelo computador. 
III. O carregador é que torna o código-objeto em relocável. 
IV. O ligador liga o código-objeto relocável com as rotinas. Essa ligação gera o código executável. 
Com base em sua análise, assinale a única opção com todas as assertivas corretas: 
A. Estão corretas III e IV apenas. 
B. Estão corretas II, III e IV apenas. 
C. Está correta apenas a III. 
D. Está correta apenas a IV. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 33 
 
Considerações finais 
Saber classificar uma linguagem dentro do(s) paradigma(s) a que pertença(m), assim como conhecer 
os domínios de programação de uma linguagem, é fundamental para seu entendimento e correta aplicação 
na hora de decidir pelo uso dessa ou aquela linguagem. 
É fundamental também que se possa conhecer os critérios de avaliação de uma linguagem e quais 
propriedades afetam cada um dos quatro critérios vistos. Dessa forma, vamos saber selecionar a que melhor 
se aplica a determinado contexto de uso. 
Por fim, e não menos importante, conhecer o mais profundamente possível o ambiente de 
desenvolvimento da linguagem, contemplando tradutores e/ou interpretadores, para que se possa pôr em 
prática o desenvolvimento do sistema, no paradigma, domínio do problema, e usando as melhores 
construções para gerar códigos legíveis, com alta facilidade de escrita, confiabilidade e, preferencialmente, 
ao menor custo possível. 
Referências 
BORGES, Luiz Eduardo. Python para Desenvolvedores. 2. ed. Rio de Janeiro: Edição do Autor, 2010. 
SEBESTA, R. W. Conceitos de Linguagens de Programação. Tradução de João Eduardo Nobrega 
Tortello. 11. ed. Porto Alegre: Bookman, 2018. Disponível na biblioteca virtual da Estácio. 
VAREJÃO, F. M. Linguagem de Programação: conceitos e técnicas. 2ª reimpressão. Rio de Janeiro: 
Elsevier, 2004. 
DIJKSTRA EW. A Discipline of Programming. Prentice Hall Inc;1976. 217. 
Explore+ 
Para saber mais sobre os assuntos tratadosneste tema, pesquise na internet sobre: 
• Objective C, que é a linguagem utilizada para desenvolvimento de aplicativos iOS e MacOS. 
• Plataformas sobre a linguagem Python. 
• Plataformas de programadores, para acompanhar as linguagens de programação mais 
usadas no mercado. 
• Visual Studio, que oferece uma cadeia de ferramentas em dispositivos móveis e na nuvem. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 34 
 
Python Básico 
Introdução 
Atualmente, o ensino de disciplinas relacionadas à programação vem crescendo na educação básica 
e no ensino superior. Nos cursos de graduação voltados à tecnologia da informação, como Engenharia da 
Computação e Ciência da Computação, é frequente que se tenha contato com mais de uma disciplina focada 
em programação. Além desses cursos, outras carreiras têm contato com a programação em disciplinas como 
Introdução à Computação ou similares. Nesses diferentes contextos, várias linguagens de programação são 
usadas, tanto para o ensino como para o desenvolvimento de projetos. 
Dentre as diversas linguagens de programação que existem, Python é considerada uma das 
principais. Por sua simplicidade de aprendizado, ela tem sido utilizada em diversos cursos universitários 
como a primeira linguagem com que os alunos têm contato ao programar. Atualmente, conta com ampla 
participação da comunidade, além de ter seu desenvolvimento aberto e gerenciado pela organização sem 
fins lucrativos Python Software Foundation. 
Recentemente, a IEEE Computer Society classificou-a como a linguagem mais indicada para 
aprender em 2020. Isso se deve à sua eficiência no desenvolvimento de machine learning, inteligência 
artificial, ciência, gestão e análise de dados. 
IEEE Computer Society 
Grupo voltado à ciência da computação, engenharia elétrica e eletrônica, apoiando e organizando congressos 
no mundo todo e divulgando artigos científicos dessas áreas. 
Linguagem Python e suas principais características 
Conceitos 
Python é uma linguagem de programação de alto nível, que permite ao programador utilizar 
instruções de forma intuitiva, tornando seu aprendizado mais simples do que o aprendizado de uma 
linguagem de baixo nível. 
Nas linguagens de baixo nível, o programador precisa se expressar de forma muito mais próxima do 
que o dispositivo “entende”, levando naturalmente a um distanciamento da linguagem utilizada para 
comunicação entre duas pessoas. 
A linguagem Python foi lançada pelo holandês Guido van Rossum no início dos anos 1990 e desde 
então tem aumentado sua participação no mundo da programação. Permite uma programação fácil e clara 
para escalas pequenas e grandes, além de enfatizar a legibilidade eficiente do código, notadamente usando 
espaços em branco significativos. 
Características da linguagem Python 
A linguagem Python tem se tornado cada vez mais popular porque, além de permitir um rápido 
aprendizado inicial, tem características importantes, tais como: 
É multiparadigma 
Apesar de suportar perfeitamente o paradigma de programação estruturada, Python também 
suporta programação orientada a objetos, tem características do paradigma funcional, com o amplo 
uso de bibliotecas, assim como permite recursividade e uso de funções anônimas. 
É interativa 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 35 
 
Permite que os usuários interajam com o interpretador Python diretamente para escrever os 
programas, utilizando o prompt interativo. Esse prompt fornece mensagens detalhadas para 
qualquer tipo de erro ou para qualquer comando específico em execução, suporta testes interativos 
e depuração de trechos de código. 
É híbrida quanto ao método de implementação 
Python usa uma abordagem mista para explorar as vantagens do interpretador e do compilador. 
Assim como Java, utiliza o conceito de máquina virtual, permitindo a geração de um código 
intermediário, mais fácil de ser interpretado, mas que não é vinculado definitivamente a nenhum 
sistema operacional. 
É portável 
Tem a capacidade de rodar em uma grande variedade de plataformas de hardware com a mesma 
interface. Ele roda perfeitamente em quase todos os sistemas operacionais, como Windows, Linux, 
UNIX, e Mac OS, sem nenhuma alteração. 
É extensível 
Permite que os programadores adicionem ou criem módulos e pacotes de baixo nível / alto nível ao 
interpretador Python. Esses módulos e pacotes de ferramentas permitem que os desenvolvedores 
tenham possibilidades amplas de colaboração, contribuindo para a popularidade da linguagem. 
Suporta bancos de dados 
Por ser uma linguagem de programação de uso geral, Python suporta os principais sistemas de 
bancos de dados. Permite escrever código com integração com MySQL, PostgreSQL, SQLite, 
ElephantSQL, MongoDB, entre outros. 
Suporta interface com usuário 
Permite escrever código de tal maneira que uma interface do usuário para um aplicativo possa ser 
facilmente criada, importando bibliotecas como Tkinter, Flexx, CEF Python, Dabo, Pyforms ou 
PyGUI wxPython. 
Pode ser usado como linguagem de script 
Permite fácil acesso a outros programas, podendo ser compilado para bytecode a fim de criar 
aplicativos grandes. 
Permite desenvolvimento de aplicações Web 
Devido à escalabilidade já citada, Python oferece uma variedade de opções para o desenvolvimento 
de aplicativos Web. A biblioteca padrão do Python incorpora muitos protocolos para o 
desenvolvimento da web, como HTML, XML, JSON, processamento de e-mail, além de fornecer 
base para FTP, IMAP e outros protocolos da Internet. 
Permite criação de aplicações comerciais 
É desenvolvido sob uma licença de código aberto aprovada pela OSI, tornando-o livremente 
utilizável e distribuível, mesmo para uso comercial. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 36 
 
Instalação 
A linguagem Python tem seu site oficial, onde é possível encontrar as últimas versões lançadas, 
notícias e documentação, entre outras informações. A versão que utilizaremos neste tema é a 3.7.7. Por 
isso, recomendamos que ela seja baixada e instalada em seu computador. Também será necessário baixar 
e instalar a IDE PyCharm, usando a versão disponível em seu site. 
Utilitários e módulos 
Apenas como exemplo, na área de Console clique no botão Python Console. No prompt interativo 
>>> que se abrirá, digite x = 5 e pressione a tecla [ENTER] ou [RETURN] do seu teclado. Observe na figura 
2 que, na área Árvore de exibição de variáveis, agora fica disponível a informação que a variável x é do tipo 
int e tem o valor 5. 
 
Fonte: Estácio de Sá 
Não se preocupe ainda com o conceito de variável, nem com o seu tipo. Veremos tudo isso 
com detalhes nos próximos módulos deste tema. 
O utilitário dir apresenta todos os atributos e métodos disponíveis para determinado tipo de dado. 
No prompt interativo >>>, digite dir(x) e pressione a tecla [ENTER] ou [RETURN] do seu teclado. 
 
Fonte: Estácio de Sá 
O utilitário help apresenta a documentação relativa a determinado tipo de dado. Caso você tenha 
alguma dúvida sobre o que é possível fazer com determinado tipo, os utilitários dir e help podem ser úteis. 
Blocos 
Em Python, os blocos são definidos pela indentação. Diferente de C e Java, que usam as chaves { 
e } para delimitar os blocos, em Python todos os blocos são iniciados com o símbolo : (dois pontos) na linha 
superior e representados pelo acréscimo de 4 (quatro) espaços à esquerda. Sem se preocupar por enquanto 
com o significado das expressões for, if, else ou range, observe a figura 4: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 37 
 
 
Fonte: Estácio de Sá 
 
A partir dessa figura, podemos destacar alguns pontos: 
Linha 1: Está mais à esquerda, assim como as linhas 2 e 11. 
Linha 2: Todas as linhas de 3 a 10 estão dentro do bloco do for da linha 2. 
Linha 3: Observe que a linha 3 temum if abrindo um bloco, dentro do qual estão as linhas 4 e 5. 
Linha 6: Por sua vez, a linha 6 tem um else abrindo outro bloco, composto pelas linhas de 7 a 10. 
Os blocos do if (linha 3) e do else (linha 6) estão no mesmo nível. 
Linha 7: Mostra outro if abrindo outro bloco – composto apenas pela linha 8 – que está no mesmo 
nível do bloco do else da linha 9 – composto apenas pela linha 10. 
Linha 11: Como a linha 11 está no mesmo nível da linha 2, ela não faz parte do bloco do for. 
Comentários 
Em Python, os comentários podem ser de uma linha ou de várias linhas. A tabela 1 mostra as formas 
de limitar um comentário, além de comparar essas formas em Python e C. 
 Python C 
Comentários de uma linha Iniciados com # Iniciados com // 
Comentários com várias linhas Limitados por “”” (três aspas duplas) no início e no fim Iniciados com /* e encerrados com */ 
 
Atenção 
É importante lembrar que os comentários não são instruções a serem executadas. Então, você pode escrever 
de forma simples e objetiva, sem obedecer às regras de sintaxe da linguagem. 
Boas práticas de programação 
Ao começar sua jornada como programador, é importante perceber que existem algumas práticas 
que não são obrigatórias, mas podem ajudar muito no seu aprendizado. Além disso, podem permitir que 
você corrija mais rapidamente erros que podem surgir no futuro e tornam seu código mais fácil de ser 
compreendido por outro programador, favorecendo o trabalho em equipe. Vamos conhecer algumas delas: 
Uma prática muito importante é utilizar comentários no seu programa, explicando o que aquele trecho 
resolve. 
Uma característica marcante da comunidade de desenvolvedores Python é manter uma lista de 
propostas de melhorias, chamadas PEP (Python Enhancement Proposals). Dentre as PEPs, destaca-se a 
PEP8, que estabelece um guia de estilo de programação. 
Agora que já vimos os principais conceitos deste módulo, é hora de testar seus conhecimentos. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 38 
 
Verificando o aprendizado 
1. Analise as afirmativas a seguir: 
I. Python é uma linguagem livre de alto nível, orientada a objetos e de difícil leitura, pois não 
permite indentação de linhas de código. 
II. Python suporta a maioria das técnicas da programação orientada a objetos. 
III. A linguagem Python e seu interpretador estão disponíveis para as mais diversas plataformas. 
São corretas: 
A. Somente II. 
B. Somente III. 
C. Somente II e III. 
D. Somente I e II. 
 
2. (2018/IF-MT/Informática) Sobre a linguagem Python, é incorreto afirmar que: 
A. Suporta os paradigmas: imperativo, orientado a objetos e funcional. 
B. Utiliza indentação para delimitar início e fim de blocos. 
C. A linguagem Python é distribuída sob licença que proíbe sua incorporação em produtos 
proprietários. 
D. Python é um software de código aberto. 
Uso de variáveis em Python 
Conceitos 
As variáveis são abstrações para endereços de memória que permitem que os programas fiquem 
mais fáceis de codificar, entender e depurar. Podemos entender que ao nomear uma variável com o 
identificador x, determinado espaço em memória passará a ter esse apelido. Em outras palavras, será 
possível acessar esse espaço de memória sabendo o seu apelido e, consequentemente, recuperar o valor 
guardado nele, que no nosso exemplo é 10. 
Uma analogia possível com o mundo real é com aquelas caixas de correio que ficam em frente às 
casas. 
Em Python, o operador de atribuição é o = (símbolo de igual). A instrução x = 10 atribui o valor 10 à 
variável x. 
No prompt interativo >>>, digite x = 10 e pressione a tecla [ENTER] ou [RETURN] do seu teclado. 
Em seguida, digite x e pressione a tecla [ENTER] ou [RETURN]. 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 39 
 
Atenção 
Observe na figura 5 que o retorno do Python Console foi 10. 
Se, posteriormente, você utilizar novamente o prompt interativo >>> para digitar x = 20 e pressionar 
a tecla [ENTER], você alterará o valor da variável x. Ou seja, você estará mudando o valor armazenado 
naquele espaço de memória, mas sem alterar seu apelido. Observe a figura 6: 
 
Fonte: Estácio de Sá 
Atenção 
Diferentemente de outras linguagens, como C ou Java, não é necessário declarar uma variável antes de utilizá-
la em Python. Basta atribuir um valor inicial à variável e utilizá-la dali em diante. Embora não seja necessário declarar 
uma variável para utilizá-la, não é possível utilizar uma variável que não tenha recebido alguma atribuição de valor. 
No prompt interativo, digite b e pressione a tecla [ENTER] ou [RETURN]. 
 
Fonte: Estácio de Sá 
Veja na figura 7 que a mensagem de erro informa que o nome b não foi definido. Ou seja, não é 
possível determinar o valor atribuído a esse nome. 
Identificadores de variáveis 
Os identificadores das variáveis podem ser compostos por letras, o underline (_) e, com exceção do 
primeiro caractere, números de 0 a 9. Veja os exemplos: 
minhaVariavel, _variavel, salario1 e salario1_2 são válidos. 
1variavel e salario-1 não são válidos. 
minhaVariavel e minhavariavel são identificadores de duas variáveis distintas. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 40 
 
Mesmo que seja um identificador permitido, nem sempre um identificador é bom para uma variável. 
Tente utilizar nomes que ajudem a entender o significado da variável para ganhar tempo quando for entender 
o código posteriormente. 
Exemplo 
salario é um nome de variável melhor que s. 
Algumas palavras são consideradas reservadas e não podem ser usadas como identificadores de 
variáveis em Python. São elas: and, as, assert, break, class, continue, def, del, elif, else, except, exec, 
finally, for, from, global, if, import, in, is, lambda, not, or, pass, print, raise, return, try, while, with e 
yield. 
Amarrações 
Chamamos de amarração (binding) a associação entre entidades de programação. Veja alguns 
exemplos: 
• Variável amarrada a um valor 
• Operador amarrado a um símbolo 
• Identificador amarrado a um tipo 
O tempo em que a amarração ocorre é chamado de tempo de amarração. Cada linguagem pode ter 
os seguintes tempos de amarração: 
Tempo de projeto da linguagem 
Os símbolos são amarrados ao operador, como * (multiplicação), ou à definição das palavras 
reservadas. 
Tempo de implementação 
Ocorre em geral nos compiladores, como a definição de faixa de valores para determinado tipo. 
Tempo de compilação 
Associação da variável ao seu tipo. Lembre-se de que Python associa a variável ao tipo, como foi 
explicado na seção anterior. 
Tempo de ligação 
A ligação de vários módulos compilados previamente, como a chamada a uma função de um 
módulo importado. Em C, utilizamos a diretiva #include para termos permissão de utilizar as funções 
de determinada biblioteca. Em Python, utilizamos o import para isto. 
Tempo de carga 
Quando o programa é carregado. Por exemplo: endereços de memória relativos são substituídos 
por endereços absolutos. 
Tempo de execução 
Associação de valores a variáveis que dependam de entradas do usuário, por exemplo. A variável 
é vinculada ao valor apenas durante a execução do programa. 
O momento em que ocorre a ligação pode ser classificado como cedo (early binding) ou tardio (late 
binding). Quanto mais cedo ocorre a ligação, maior a eficiência de execução do programa, porém menor a 
flexibilidade das estruturas disponibilizadas. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 41 
 
Amarração de tipo 
As amarrações de tipo vinculam a variável ao tipo do dado. Elas podem ser: 
Estáticas: Ocorrem antes da execução e permanecem inalteradas. Em C, declaramos int a. 
Dinâmicas: Ocorrem durante a execução e podem ser alteradas. É o caso do Python. 
Veja a figura 8: 
 
Fonte: Estácio de Sá 
Perceba que a chamada type (parâmetro) retorna o tipo doparâmetro informado entre parênteses. 
Observe que a variável valor recebeu 10 e, com isso, ficou vinculada ao tipo int. Porém, ao receber o valor 
‘a’, passou a estar vinculada ao tipo str (string). 
Escopo de visibilidade 
O escopo define em quais partes do programa uma variável é visível. Cada nome de variável em 
Python tem seu escopo e fora desse escopo o nome não existe, gerando um erro quando se tenta referenciar 
esse nome. Quanto ao escopo, chamamos as variáveis de globais ou locais. 
Variáveis globais 
Todos os nomes atribuídos no prompt interativo ou em um módulo fora de qualquer função são 
considerados como de escopo global. Por exemplo, ao executar a instrução da figura 9, a variável x é uma 
variável global. 
 
Fonte: Estácio de Sá 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 42 
 
Variáveis locais 
Para exemplificar o uso de variáveis com escopo local, vamos utilizar uma função definida pelo 
desenvolvedor. Não se preocupe com esse tipo de função por enquanto, você aprenderá mais detalhes 
posteriormente. Observe a figura 10: 
 
Fonte: Estácio de Sá 
As linhas 2, 3 e 4 compõem o bloco interno à função chamada multiplicador(). Embora as variáveis 
das linhas 2 e 7 tenham o mesmo nome, elas são abstrações a endereços de memória diferentes. Dentro 
da função multiplicador(), a chamada ao nome a recupera o valor 2. Fora da função multiplicador(), a 
chamada ao nome a recupera o valor 3. Veja a execução na figura 11: 
 
Fonte: Estácio de Sá 
Agora, observe a função multiplicador() com uma pequena alteração, em que retiramos a 
inicialização da variável a dentro da função. 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 43 
 
Na linha 6, ao se chamar a função multiplicador(), a variável a será procurada. Como não existe 
uma variável a no bloco interno da função, ela é procurada como variável global. Uma vez encontrada, o 
valor recuperado é 3. Ao executar esse exemplo, você verá: 
 
Fonte: Estácio de Sá 
Usamos este exemplo para mostrar que o interpretador Python pode procurar o mesmo nome de 
variável em diferentes escopos. A ordem utilizada para a procura é: 
1. A chamada da função delimitadora 
2. Variáveis globais 
3. O módulo builtins 
Perceba que, se a variável a é inicializada na função multiplicador(), qualquer chamada a esse 
nome dentro da função resultará na referência a essa variável local. Mas seria possível alterar a variável a 
global com uma instrução dentro da função multiplicador()? Sim, utilizando-se a palavra reservada global. 
Veja como isso poderia ser feito na figura 14 e o seu resultado na figura 15: 
 
Fonte: Estácio de Sá 
Tipos de escopo 
Os tipos de escopo são: 
Estático 
O escopo é baseado na descrição textual do programa e as amarrações são feitas em tempo de 
compilação. É o caso de C, C++ e Java, por exemplo. 
Dinâmico 
O escopo é baseado na sequência de chamada dos módulos (ou funções). Por isso, as amarrações 
são feitas em tempo de execução. É o caso do Python. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 44 
 
O fato de Python ser de escopo dinâmico traz alguns problemas, como a perda de eficiência – uma 
vez que os tipos precisam ser verificados em tempo de execução – e a redução na legibilidade – porque é 
difícil determinar a sequência exata de todas as chamadas de função. 
Tempo de vida 
Embora escopo e tempo de vida tenham uma relação próxima, eles são conceitos diferentes. 
Observe: 
• Escopo é um conceito textual 
• Tempo de vida é um conceito temporal 
 
As variáveis globais têm o tempo de vida que é o de execução do programa, ao passo que as 
variáveis locais somente existem no intervalo de duração da função ou do bloco a que se limitam. 
Constantes 
Em Python, não existe o conceito de constante. Se você precisar de uma constante ao longo de sua 
jornada como programador, atribua o valor a uma variável e tome cuidado para não mudar esse valor. 
Dica 
Uma dica é iniciar o nome dessa variável com c_ ou utilizar todas as letras maiúsculas, o que vai diferenciar 
essa variável das outras. Por exemplo, é possível utilizar a expressão c_PI = 3.141592 para armazenar o valor de PI e 
agilizar o cálculo de área e perímetro de um círculo, ou utilizar a expressão PRECISION = 0.001 para armazenar a 
precisão a ser utilizada em qualquer cálculo matemático no seu programa. 
É importante ficar atento ao uso correto das variáveis, especialmente observando as questões de 
escopo e visibilidade, para evitar que algum cálculo seja realizado corretamente, mas com resultado 
diferente do esperado por você ao programar. 
Verificando o aprendizado 
1. (2017/IF-CE/Técnico de Laboratório/Informática) Considere o trecho do programa Python abaixo: 
def func(): 
 x = 1 
 print(x) 
x = 10 
func() 
print(x) 
Os valores impressos, ao se executar o programa, são, respectivamente: 
A. 1 e 1. 
B. 10. 
C. 1 e 10. 
D. 10 e 10. 
 
2. (MS CONCURSOS/2016/Creci 1° Região (RJ)/Analista de TI) Qual alternativa representa a declaração de 
uma variável na linguagem de programação Python? 
A. var valor = 3; 
B. boolean inicio = falso; 
C. texto = ‘texto de exemplo’ 
D. int i = 1; 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 45 
 
Tipos de dados e as expressões em Python 
Conceitos 
Neste módulo, você será apresentado aos tipos padrão incorporados ao interpretador Python. Os 
principais tipos internos são numéricos, sequenciais e dicionários. Classes, instâncias e exceções 
também são tipos padrão, mas não entraremos em detalhes neste tema. Para ter nosso primeiro contato 
com expressões em Python, use o prompt interativo >>>. 
Digite a expressão algébrica 5 + 8 e pressione a tecla [ENTER]. Observe o resultado na figura 16: 
 
Fonte: Estácio de Sá 
O Python Console permite que você calcule expressões algébricas como uma calculadora, além de 
executar instruções básicas em Python. 
Tipos numéricos 
Existem três tipos numéricos distintos em Python: inteiros, números de ponto flutuante e números 
complexos. Além disso, os booleanos são um subtipo dos inteiros. 
O tipo int 
É o tipo usado para manipular números inteiros. Fazendo uma analogia com a Matemática, o tipo int 
é usado para elementos do conjunto dos inteiros (Z). 
Diferentemente de outras linguagens, como C ou Java, a linguagem Python não limita o tamanho de 
uma variável de qualquer tipo, logo, não existe um valor inteiro máximo definido. O limite depende da 
quantidade de memória disponível no computador. De volta ao Python Console, veja algumas coisas 
interessantes. 
Digite 1_000_000 e pressione a tecla [ENTER]. 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 46 
 
Python permite que você utilize o underline (_) como separador de milhar. Isso ajuda a visualizar 
números com muitos dígitos. Para encerrarmos este primeiro contato com o tipo int, verifique que o valor do 
exemplo anterior é inteiro. 
Digite type(1_000_000) e pressione a tecla [ENTER]. 
 
Fonte: Estácio de Sá 
O tipo float 
É o tipo usado para manipular números com parte inteira e parte decimal, chamados de números de 
ponto flutuante. Fazendo uma analogia com a Matemática, o tipo float é usado para elementos do conjunto 
dos reais (R). 
Para diferenciar um número real de um inteiro, é possível utilizar a parte decimal zerada. No prompt 
interativo >>>, digite type(50.0) e pressione a tecla [ENTER]. 
 
 
Fonte: Estácio de Sá 
Atenção 
Vale ressaltar que devemos usar o ponto para separar a parte inteira da parte decimal, e não a vírgula. 
No prompt, digite 50.0 (com ponto) e pressione [ENTER]. Em seguida, digite 50,0 (com vírgula) e 
pressione a tecla [ENTER]. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 47 
 
 
Fonte: Estácio de Sá 
Ao usara vírgula como separador em Python, o que ocorre, na verdade, é a criação de uma tupla de 
dois elementos, e não o tipo float. Você verá mais detalhes sobre tuplas em um momento posterior. 
Embora os tipos int e float sejam semelhantes, por tratarem de números, eles têm propriedades um 
pouco diferentes. Em expressões algébricas, sempre que somamos, subtraímos ou multiplicamos apenas 
elementos do tipo int, o resultado é int. Porém, basta um operando do tipo float para que o resultado seja 
float. Observe a figura 21: 
 
Fonte: Estácio de Sá 
Vamos analisar a exponenciação. Para realizar essa operação matemática, utilizamos o operador 
(**). Veja a figura 22: 
 
Fonte: Estácio de Sá 
Veja que basta que a base seja float para que o resultado também o seja. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 48 
 
Atenção 
Diferentemente de outras linguagens, como C, a divisão de dois números inteiros não necessariamente tem 
resultado inteiro. 
Digite 5/2 e pressione [ENTER]. 
 
Fonte: Estácio de Sá 
Para obter o quociente inteiro e o resto, quando dois inteiros são divididos, é necessário utilizar os 
operadores // e %, respectivamente. Ao dividir 21 por 2, temos quociente 10 e resto 1. Observe a figura 24: 
 
 
Fonte: Estácio de Sá 
O tipo complex 
É o tipo utilizado para manipular números complexos, na forma x + yj, sendo x a parte real e y a 
parte imaginária do complexo. 
Veja dois exemplos de variáveis do tipo complex nas figuras 25 e 26, em que a parte real é 2 e a 
parte imaginária é 5: 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 49 
 
 
Fonte: Estácio de Sá 
A chamada r.conjugate() retorna o conjugado do número complexo r, em que a parte real é mantida 
e a parte imaginária tem o seu sinal trocado. 
O tipo bool 
Uma expressão algébrica, como vimos nos exemplos dos tipos int e float, é avaliada como um 
número, seja desses tipos ou de outro tipo numérico admitido em Python. Porém, utilizar expressões não 
algébricas também é bastante comum. E uma boa notícia é que Python pode avaliar expressões desse tipo 
também. Essa é uma diferença entre Python e outras linguagens, como C, por exemplo, em que não existe 
o tipo bool. 
No prompt interativo >>>, digite a expressão 2 < 3 e pressione [ENTER]. Observe o resultado na 
figura 27: 
 
Fonte: Estácio de Sá 
Repare que o resultado dessa expressão não é um número, mas sim a palavra True. Caso você 
colocasse a expressão 2 > 3, o resultado seria False, como pode ver na figura 28. 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 50 
 
Saiba mais 
As expressões que você viu nos dois exemplos são chamadas de expressões booleanas. Trata-se de 
expressões que podem ser avaliadas com um dos dois valores booleanos: True ou False. Assim, em Python, existe o 
tipo bool, utilizado para permitir o tratamento de expressões como essas. 
Agora, vamos ver o operador not, que é um operador unário, ou seja, só precisa de um operando. 
Esse operador inverte o valor booleano, ou seja, se o valor original for True, not(valor) terá o valor False. 
E vice-versa. 
No prompt interativo >>>, digite a expressão not(2 < 3) e pressione [ENTER]. 
 
Fonte: Estácio de Sá 
É possível também escrever expressões booleanas compostas, utilizando conectivos como E OU. 
Vamos ver mais detalhes sobre essas expressões ainda neste módulo. 
Operadores numéricos 
Operadores matemáticos 
Os operadores matemáticos são muito semelhantes àqueles que vimos ao longo de nossa jornada 
como estudantes, aprendendo Álgebra e Aritmética na escola. Existem algumas pequenas diferenças, como 
a divisão (que pode ser a usual ou a divisão inteira). Mas é possível identificar operações que fizemos ao 
longo de toda nossa vida. A tabela 2 lista os operadores de expressão aritmética disponíveis em Python. 
Operação matemática Símbolo usado 
Exemplo 
Equação Resultado 
Soma + 2.5 + 1.3 3.8 
Subtração - 2.5 - 1.3 1.2 
Multiplicação * 2.5 * 1.3 3.25 
Divisão / 2.5/1.3 1.923076923076923 
Divisão inteira // 9/2 4 
Resto na divisão inteira % 9%2 1 
Valor absoluto abs(parâmetro) abs(-2.5) 2.5 
Exponenciação ** 2**4 16 
 
Além das operações algébricas, é possível realizar operações de comparação. Os operadores de 
comparação têm como resultado um valor booleano (True ou False). Observe a tabela 3: 
Símbolo usado Descrição 
< Menor que 
<= Menor ou igual a 
> Maior que 
>= Maior ou igual a 
== Igual 
!= Não igual 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 51 
 
Atenção 
Cabe observar que o operador utilizado para comparar se dois valores são iguais é o ==, ou seja, duplo sinal 
de igual. Tome cuidado para não confundir com o operador de atribuição, que é representado pelo sinal de igual apenas 
uma vez (=). 
Existe outra lista de operadores que executam operações matemáticas, mas, além disso, atualizam 
o valor da variável utilizada. Eles são chamados de operadores compostos e serão detalhados no módulo 
4. Para mais funções matemáticas, você pode utilizar os módulos matemáticos math e fractions. 
Operadores booleanos 
As expressões booleanas são aquelas que podem ter como resultado um dos valores booleanos: 
True ou False. É comum utilizarmos os operadores de comparação em expressões booleanas, mas não só 
eles. 
Assim como é possível escrever expressões algébricas complexas concatenando diversas 
expressões menores, podemos escrever expressões booleanas grandes, com os operadores and, or e not. 
Observe o comportamento dos operadores booleanos nas tabelas 4, 5 e 6. 
p not (p) 
True False 
False True 
 
p q p and q 
True True True 
True False False 
False True False 
False False False 
 
p q p or q 
True True True 
True False True 
False True True 
False False False 
 
Tipos sequenciais 
Existem três tipos sequenciais básicos em Python: listas, tuplas e objetos range. Além dos tipos 
básicos citados, existe um tipo especial criado para tratamento de dados textuais: o tipo str (string). 
Assim como em C ou Java, a indexação dos itens é iniciada com 0 e cada item tem o seu índice 
incrementado uma unidade em relação ao item anterior. Porém, Python também permite a indexação com 
valores negativos. O valor -1 é o índice do último item, e cada item anterior é decrementado de uma unidade 
em relação ao sucessor. Observe a tabela 7: 
índice 0 1 2 3 4 
s t e s t e 
índice negativo -5 -4 -3 -2 -1 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 52 
 
Strings 
Em uma variável do tipo str, é possível armazenar letras, números, espaços, pontuação e diversos 
símbolos. Diferentemente da linguagem C, não existe o tipo char. Cada caractere em Python é uma string. 
Para delimitar uma string, podemos utilizar: 
1. Aspas simples: ‘uma string' 
2. Aspas duplas: “uma string” 
3. Aspas simples triplas: ‘’’uma string’’’ 
4. Aspas duplas triplas: “””uma string””” 
A Figura 30 ilustra um exemplo de delimitadores de strings: 
 
Fonte: Estácio de Sá 
Existem alguns métodos interessantes para tratar strings em Python. Entre eles, ressaltamos: 
1. upper: Transforma todas as letras em maiúsculas. 
2. lower: Transforma todas as letras em minúsculas. 
3. split: Quebra a string em substrings. 
Veja os exemplos a seguir: 
 
Fonte: Estácio de Sá 
Saiba mais 
A lista gerada com o método split() tem três elementos, porque a string original tinha três palavras. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 53 
 
Listas 
Listas são sequências mutáveis, normalmente usadas para armazenar coleções de itens 
homogêneos. Uma lista pode ser criada de algumas maneiras, tais como: 
[ ] → Usando um par de colchetes para denotar uma lista vazia. 
[a], [a, b, c] → Usando colchetes, separando os itens por vírgulas. 
[x for x in iterable] → Usando a compreensãode lista. 
list() ou list(iterable) → Usando o construtor do tipo list. 
Saiba mais 
iterable pode ser uma sequência, um container que suporte iteração ou um objeto iterador. Por exemplo, 
list('abc') retorna ['a', 'b', 'c'] e list( (1, 2, 3) ) retorna [1, 2, 3]. Se nenhum argumento for passado, o construtor cria uma 
lista vazia: [ ]. 
Tuplas 
Tuplas são sequências imutáveis, tipicamente usadas para armazenar coleções de itens 
heterogêneos. Elas são aplicadas também quando é necessário utilizar uma sequência imutável de dados 
homogêneos. Uma tupla pode ser criada de algumas maneiras, tais como: 
( ) → Usando um par de parênteses para denotar uma tupla vazia. 
a, b, c ou (a, b, c) → Separando os itens por vírgulas. 
tuple() ou tuple(iterable) → Usando o construtor do tipo tuple. 
Novamente, iterable pode ser uma sequência, um container que suporte iteração ou um objeto 
iterador. Por exemplo, tuple('abc') retorna ('a', 'b', 'c') e tuple( [1, 2, 3] ) retorna (1, 2, 3). Se nenhum argumento 
for passado, o construtor cria uma tupla vazia: (). 
Atenção 
Note que o uso das vírgulas é o que gera a tupla, e não o uso de parênteses. Os parênteses são opcionais, 
exceto no caso em que queremos gerar uma tupla vazia. 
Range 
O tipo range representa uma sequência imutável de números e frequentemente é usado em loops 
de um número específico de vezes, como o for. 
Ele pode ser chamado de maneira simples, apenas com um argumento. Nesse caso, a sequência 
começará em 0 e será incrementada de uma unidade até o limite do parâmetro passado (exclusive). Por 
exemplo, range(3) cria a sequência (0, 1, 2). 
Para que a sequência não comece em 0, podemos informar o início e o fim como parâmetros, 
lembrando que o parâmetro fim não entra na lista (exclusive o fim). O padrão é incrementar cada termo em 
uma unidade. Ou seja, a chamada range(2, 7) cria a sequência (2, 3, 4, 5, 6). 
Saiba mais 
Também é possível criar sequências mais complexas, indicando os parâmetros de início, fim e passo, nessa 
ordem. O passo é o valor que será incrementado de um termo para o próximo. Por exemplo, range(2, 9, 3) cria a 
sequência (2, 5, 8). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 54 
 
Operadores sequenciais comuns 
Os operadores sequenciais permitem a manipulação dos tipos sequenciais, inclusive as strings. Vale 
ressaltar a sobrecarga dos operadores + e *, que realizam operações diferentes quando os operandos são 
numéricos ou sequenciais. 
Exemplo 
O operador == verifica se as strings dos dois lados são iguais. Porém, os operadores < e > comparam as strings 
usando a ordem do dicionário. 
A tabela a seguir traz um pequeno conjunto dos operadores disponíveis em Python para manipulação 
de sequências. Lembre-se de que você pode utilizar o utilitário help no Python Console para verificar a lista 
completa. Para isso, basta digitar help(str) e pressionar [ENTER] no teclado. 
Uso Resultado 
x in s True se x for um subconjunto de s 
x not in s False se x for um subconjunto de s 
s + t Concatenação de s e t 
n*s Concatenação de n cópias de s 
s[i] Caractere de índice i em s 
len(s) Comprimento de s 
min(s) Menor item de s 
max(s) Maior item de s 
 
Dicionários 
Os dicionários permitem que itens de uma sequência recebam índices definidos pelo usuário. Um 
dicionário contém pares de (chave, valor). O formato geral de um objeto dicionário é: 
{<chave 1>:<valor 1>, <chave 2>:<valor 2>, ..., <chave i>:<valor i>} 
Exemplo 
Poderíamos criar um dicionário em que cada pessoa fosse representada pelo seu CPF, com nome e 
sobrenome. Para isso, teríamos: 
 
Fonte: Estácio de Sá 
Na figura 32, o dicionário tem 3 entradas. Observe como foi possível recuperar nome e sobrenome de uma 
entrada, baseado na chave informada ‘111222333-44’. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 55 
 
Precedência de operadores 
Ao escrever uma expressão algébrica, o programador pode utilizar a precedência de operadores 
existente em Python (implícita) ou explicitar a ordem em que ele deseja que a expressão seja avaliada. 
Exemplo 
Por exemplo, a expressão 3 + 2 * 5 tem como resultado 25 ou 13? Aprendemos no ensino fundamental que as 
operações de produto e divisão têm precedência sobre as operações de soma e subtração. Ou seja, um produto será 
realizado antes de uma soma, na mesma expressão. Assim, a expressão acima tem como resultado 13. Isso ocorre 
sempre que não forem explicitadas outras relações de precedência com o uso de parênteses. Caso o programador 
quisesse forçar que a soma ocorresse primeiro, ele deveria escrever assim: (3 + 2) * 5. 
Sempre que o programador quiser forçar a ocorrência de uma operação antes de outras, ele pode 
utilizar os parênteses para aumentar a prioridade sobre ela. A tabela a seguir traz as relações de precedência 
entre os operadores, com as linhas mais altas tendo prioridade sobre as linhas mais baixas. Ou seja, elas 
ocorrem primeiro. Dentro da mesma linha, a precedência é da esquerda para a direita. 
Operador Descrição 
[expressões ...] Definição de lista 
x[ ], x[índice : índice] Operador de indexação 
** Exponenciação 
+x, -x Sinal de positivo e negativo 
*, /, //, % Produto, divisão, divisão inteira, resto 
+, - Soma, subtração 
in, not in, <, <=, >, >=, <>, !=, == Comparações, inclusive a ocorrência em listas 
not x Booleano NOT (não) 
and Booleano AND (e) 
or Booleano OR (ou) 
 
Atenção 
É importante ficar atento ao uso correto dos operadores, respeitando a precedência entre eles, para evitar que 
algum cálculo seja realizado corretamente, mas com resultado diferente do esperado por você ao programar. 
Conversões de tipos 
Quando temos tipos diferentes envolvidos na mesma expressão, o Python converte implicitamente 
cada operando para o tipo mais abrangente envolvido na expressão. Estamos usando a palavra abrangente, 
mas poderíamos falar que existem tipos que englobam (ou contêm) outros. 
Exemplo 
Um número do tipo int pode ser visto como um float com a parte decimal nula. Porém, o inverso não é verdade. 
Ou seja, o conjunto dos inteiros (int) é um subconjunto do conjunto dos reais (float). Assim, a expressão 5 + 0.68 – que 
envolve um int e um float – tem como resultado 5.68. O inteiro 5 é convertido pelo Python para o número de ponto 
flutuante 5.0 antes que a soma (de dois valores float) seja realmente efetuada. 
Uma conversão implícita não intuitiva é a dos valores booleanos True e False em inteiros, 
respectivamente, 1 e 0. Veja os exemplos a seguir: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 56 
 
 
Fonte: Estácio de Sá 
Com isso, podemos perceber a seguinte relação entre os tipos bool, int e float: 
 
Fonte: Estácio de Sá 
Além das conversões implícitas, o programador também pode usar as conversões explícitas, quando 
ele força que o valor seja tratado como de determinado tipo. Para isso, é necessário usar o construtor do 
tipo desejado, com o valor passado como parâmetro (entre parênteses). Veja o exemplo a seguir: 
 
Fonte: Estácio de Sá 
O int 2 pode ser tratado naturalmente como o float 2.0, basta acrescentar a parte decimal nula. 
Porém, ao tentar tratar um float como int, ocorre a remoção da parte decimal. 
Atenção 
Fique atento, porque não é uma aproximação para o inteiro mais próximo, e sim o truncamento. 
Agora que você já viu os principais tipos de dados suportados em Python, vamos exercitar e verificar 
o aprendizado. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 57 
 
Verificando o aprendizado 
1. Considere a expressão a seguir: 2 + 3 – 4 ** 2 + 5 / 2 – 5 // 2. Assinale a opção com o valor correto dessa 
expressão em Python. 
A. -10.5 
B. -1 
C. 1.5 
D. 2 
 
2. (Adaptada de COMPERVE/2019/UFRN/Engenharia da Computação) Python é uma linguagem interpretada 
muito utilizada. Não requer tipagem de variáveis e sua sintaxeindentada favorece a organização do código. Uma das 
suas funcionalidades mais poderosas são as listas. Considere o código em Python do quadro abaixo: 
 
Fonte: Estácio de Sá 
A saída correta correspondente às linhas 2 e 4 do código é: 
A. 2 e 4. 
B. 4 e 16. 
C. 2 e 16. 
D. 4 e 4. 
O operador + realiza operações de soma para tipos numéricos e concatenação para tipos sequenciais. Assim, 
a variável a na linha 1 passa a ser composta dos itens ‘UF’ e ‘RN’. Assim, a chamada len(a) retorna o tamanho 2, 
número de elementos de a. De forma semelhante, o operador * realiza operações de multiplicação para tipos numéricos 
e concatenação de cópias para tipos sequenciais. Assim, a variável b na linha 3 passa a ser a lista ['4', '4', '4', '4']. E a 
chamada len(b) retorna o tamanho 4, número de elementos de b. 
Formas de atribuição, de entrada e saída de dados em Python 
Conceitos 
Já vimos, de maneira básica, como podemos atribuir valor a uma variável, no módulo 2. Vamos agora 
conhecer outras formas de atribuição. 
Sentenças de atribuição 
Atribuição simples 
Chamamos de atribuição simples a forma que já utilizamos neste tema, com uma expressão parecida 
com x = 10. Nessa atribuição, a variável x recebe o valor 10. 
Atribuição múltipla 
Python também permite a atribuição múltipla, ou seja, mais de uma variável receber atribuição na 
mesma linha. Veja o exemplo na figura 36: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 58 
 
 
Fonte: Estácio de Sá 
Atenção 
Observe que as variáveis x e y receberam atribuição na mesma instrução, com a variável x armazenando o 
valor 2, e a variável y armazenando o valor 5. 
Operadores de atribuição compostos 
Os operadores de atribuição compostos executam operações matemáticas e atualizam o valor da 
variável utilizada. Por exemplo, veja a figura 37: 
 
Fonte: Estácio de Sá 
A variável x inicialmente recebeu o valor 10. Em seguida, a instrução x = x + 1, que causa estranheza 
quando lembramos da matemática aprendida ao longo da vida, é muito comum quando estamos 
programando. Essa instrução significa “acrescente uma unidade ao valor de x e guarde este resultado na 
própria variável x”. Como x valia 10, o resultado do lado direito do operador (=) é 11. Esse resultado é, então, 
armazenado na própria variável x. 
Essa operação de acrescentar determinado valor a uma variável e armazenar o resultado na própria 
variável poderia ser feita com o operador += (mais igual). Veja a figura 38: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 59 
 
 
Fonte: Estácio de Sá 
Na tabela 10, estão os operadores compostos disponíveis em Python. Considere a variável x, com o 
valor inicial 10, para verificar os resultados. 
Nome Símbolo usado 
Exemplo 
Instrução Resultado 
Mais igual += x += 2 x passa a valer 12 
Menos igual -= x -= 2 x passa a valer 8 
Vezes igual *= x *= 2 x passa a valer 20 
Dividido igual /= x /= 2 x passa a valer 5 
Módulo igual %= x %= 3 x passa a valer 1 
 
Atenção 
Diferente de C, em Python não é possível incrementar ou decrementar uma variável com um operador unário, 
como o ++ ou --. 
Troca de variáveis 
Um dos problemas iniciais que envolvem atribuição de valores a variáveis é a troca entre duas delas. 
Suponha que as variáveis a e b armazenem, respectivamente, os valores 1 e 2. Caso quiséssemos inverter 
os valores em linguagens como C ou Java, seria necessário usar uma variável auxiliar, com uma sequência 
de instruções exibida na figura a seguir: 
 
Fonte: Estácio de Sá 
Em Python, é possível fazer essa troca de uma maneira muito mais fácil. Veja o uso da atribuição 
múltipla, nesse caso, na figura a seguir: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 60 
 
 
Fonte: Estácio de Sá 
O primeiro programa em python 
Para escrever um programa em Python, será essencial utilizar as formas de saída de dados para 
exibir ao usuário mensagens e resultados de operações. Caso você deseje que o usuário informe algum 
dado para que seu programa processe, será necessário utilizar as formas de entrada de dados. 
Para criar seu primeiro programa, clique com o botão direito do mouse no nome do projeto, na guia 
de navegação do lado esquerdo. Em seguida, escolha a opção New > File. 
 
Fonte: Estácio de Sá 
Atribua um nome ao seu arquivo. Neste primeiro exemplo, vamos chamar de primeiro_programa.py 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 61 
 
Ao nomear o arquivo, será aberta uma nova aba, do lado direito, com o espaço para que você 
efetivamente digite as instruções. 
 
Fonte: Estácio de Sá 
Saída de dados com a função print() 
A função print() em Python atua de forma semelhante à printf() em C. Para um programador iniciante, 
as maiores diferenças entre elas são: 
• Duas chamadas da print() em Python são impressas na tela em linhas diferentes, sem a 
necessidade do uso do caractere ‘\n’ para pular a linha, como ocorre na printf() em C. 
• Uma chamada da print() em Python permite a impressão de valores de variáveis sem a 
indicação do formato, como ocorre na printf() em C, quando precisamos escrever %c, %d 
ou %f, por exemplo. 
Para escrever seu Hello World em Python, digite a seguinte linha, exatamente como está escrita: 
print(“Hello World”) 
Em seguida, clique com o botão direito do mouse sobre o nome do programa e escolha a opção Run 
‘primeiro_programa’. Também é possível executar com a combinação de teclas CTRL+Shift+ F10. Após 
executar, observe o console na figura 44: 
 
Fonte: Estácio de Sá 
Veja que foi impresso no console exatamente o que colocamos entre aspas, ao chamar a função 
print(). Essa é a primeira forma de saída de dados: usar a função print() com uma string sendo passada 
como parâmetro (entre os parênteses). É importante perceber que a função print(), além de imprimir a string, 
também salta o cursor para a próxima linha. 
Como você deve ter percebido, o que a função print() recebeu entre parênteses foi uma string. Ou 
seja, poderíamos ter passado para ela uma string definida anteriormente, como no exemplo a seguir: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 62 
 
 
Fonte: Estácio de Sá 
Também poderíamos ter passado como parâmetro uma variável definida anteriormente. A função 
print() vai trabalhar com o valor dessa variável. Observe as figuras 46 e 47: 
 
Fonte: Estácio de Sá 
Entrada de dados com a função input() 
Quando o programador quiser que o usuário entre com algum valor, ele deverá exibir na tela o seu 
pedido. Em C, é necessário utilizar a função printf() para escrever a solicitação ao usuário e a função scanf() 
para receber a entrada e armazenar em uma variável. Em Python, é possível utilizar a função input(). Ela 
tanto exibe na tela o pedido, como permite que o valor informado pelo usuário seja armazenado em uma 
variável do seu programa. Analise a figura 48: 
 
Fonte: Estácio de Sá 
A linha 1 fará com que a frase Entre com seu nome: seja exibida no console, mas a execução do 
programa fica travada até que o usuário aperte [ENTER] no teclado. Tudo o que foi digitado até o [ENTER] 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 63 
 
vai ser armazenado na variável nome. A linha 2 fará a exibição do conteúdo da variável nome. Veja o 
resultado no console, com o usuário tendo digitado Fulano de Tal. 
 
Fonte: Estácio de Sá 
Atenção 
É importantíssimo perceber que a função input() trata tudo o que for digitado pelo usuário como uma string, 
armazenando na variável designada pelo programador para isso. Mesmo que o usuário entre com apenas uma letra 
ou um número, isso será armazenado como uma string na variável. 
Vamos analisar o exemplo a seguir: 
 
Fonte: Estácio de Sá 
Veja o console quando o programa é executado: 
 
Fonte: Estácio de Sá 
Apostila de Paradigmasde Linguagens de Programação em Python 
Marcio Quirino - 64 
 
O usuário digitou 3 e [ENTER]. Mesmo sendo um valor, a variável numero trata como a string ‘3’. 
Isso impede que seja realizada a operação de soma com o inteiro 2, por exemplo. Poderíamos também usar 
a instrução print(type(numero)) na linha 2 para confirmar. Veja: 
 
Fonte: Estácio de Sá 
A função eval() 
A função eval() recebe uma string, mas trata como um valor numérico. Veja o exemplo a seguir: 
 
Fonte: Estácio de Sá 
Mesmo tendo recebido a string ‘1+2’ como parâmetro, a função eval() efetuou a soma de 1 com 2. 
Observe que confirmamos que s é uma string com a instrução type(s). 
Para tratar a entrada do usuário como um número e, com isso, realizar operações algébricas, por 
exemplo, é necessário utilizar a função eval() em conjunto com a input(). Veja o próximo exemplo: 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 65 
 
Mão na massa 
Como exercício prático, tente escrever um programa para calcular e informar o IMC (índice de massa 
corpórea) do usuário, que deverá fornecer seu peso e sua altura. Lembre-se que o IMC é calculado pela 
fórmula: 
 
Uma solução simples é a da figura 57: 
 
Fonte: Estácio de Sá 
Saída formatada de dados 
Quando desejamos que a saída siga determinado padrão – por exemplo, de hora ou de data – 
existem algumas possibilidades para usar a função print(). É sempre possível utilizar a concatenação de 
strings, com o operador +, para montar a frase como quisermos. Suponha que tenhamos as seguintes 
variáveis: 
hora = 10 minutos = 26 segundos = 18 
Poderíamos chamar a função print() com o separador : da seguinte forma: 
 
Fonte: Estácio de Sá 
Porém, existe outra possibilidade, usando o método format(). Ele permite que a chamada à função 
print() fique muito parecida com as chamadas à função printf() em C, com passagem de parâmetros a serem 
colocados em ordem na string. Com o método format(), podemos montar a string com as chaves {} indicando 
onde entrarão valores, passados como parâmetros separados por vírgulas. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 66 
 
 
Fonte: Estácio de Sá 
É importante observar que a quantidade de chaves precisa ser igual à quantidade de variáveis 
passadas como parâmetros no método format(). Seria muito bom se não precisássemos nos preocupar com 
essa correspondência para evitar erros bobos. E isso é possível! Para tornar a saída formatada ainda mais 
intuitiva, basta utilizar a letra ‘f’ no início dos parâmetros da função print() e colocar cada variável dentro das 
chaves na posição em que deve ser impressa. Veja como fica ainda mais fácil entender: 
 
Fonte: Estácio de Sá 
Também é possível especificar a largura de campo para exibir um inteiro. Se a largura não for 
especificada, ela será determinada pela quantidade de dígitos do valor a ser impresso. Veja a figura 62: 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 67 
 
Observe que os valores 10 e 100 foram impressos com espaços em branco à esquerda. Isso ocorreu 
porque definimos que a primeira variável deveria ser impressa com 4 espaços com {:4} (2 foram ocupados 
e 2 ficaram em branco), e que a segunda variável deveria ser impressa com 5 espaços com {:5} (3 foram 
ocupados e 2 ficaram em branco). 
Saiba mais 
Também é válido perceber que o padrão é alinhar os valores à direita do espaço reservado para a impressão 
da variável. 
O método format() também pode ser usado para imprimir valores de ponto flutuante com a precisão 
definida. Veja a figura 63: 
 
Fonte: Estácio de Sá 
Ao usar {:8.5}, estamos determinando que a impressão será com 8 espaços, mas apenas 5 serão 
utilizados. 
Impressão de sequências 
Python também permite a impressão de sequências com mais possibilidades que C, incluindo as 
strings. Para imprimir um vetor em C, por exemplo, precisamos chamar a printf() item a item. Em Python, 
basta chamar a função print() passando como parâmetro a sequência. Veja a figura 64: 
 
Fonte: Estácio de Sá 
Para imprimir uma substring, por exemplo, basta utilizar os colchetes para indicar o intervalo de 
índices que deve ser impresso. Vale lembrar que o primeiro caractere da string é indexado com 0. Veja a 
figura 65: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 68 
 
 
Fonte: Estácio de Sá 
Atenção 
Usar [0:4] provoca a impressão dos índices 0, 1, 2 e 3, mas não do índice 4. Analogamente, usar [2:8] provoca 
a impressão dos índices de 2 a 7, mas não do 8. 
Também é possível imprimir a string como lida da direita para a esquerda. Para isso, deve-se utilizar 
[: : -1]. Esse valor -1 indica que a leitura dos caracteres será feita no sentido oposto ao tradicional. Observe 
a figura 66: 
 
Fonte: Estácio de Sá 
Atenção 
Fique atento quando utilizar o intervalo na impressão no sentido inverso, porque os limites do intervalo devem 
respeitar esse sentido. 
Verificando o aprendizado 
1. (2015/PGE-RO/Técnico da Procuradoria/Tecnologia da Informação) Na linguagem Python, um comando 
como a=input("XXX") provoca: 
A. A associação à variável “a" de uma função denominada “XXX" que pertence à biblioteca “input". 
B. A criação de uma lista de valores denominada “a" cujo elemento inicial é a string “XXX". 
C. A leitura de um valor do arquivo de entrada correntemente designado de acordo com um formato 
expresso pela string “XXX". 
D. Um prompt no dispositivo de saída e a leitura de um valor que é armazenado na variável “a". 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 69 
 
2. (2015/TJ-BA/Analista Judiciário/Tecnologia da Informação/Reaplicação) Analise o trecho de programa 
Python apresentado a seguir. 
L = [1,2,3,4,5,6,7,8] 
print L[::-1] 
Ao ser executado, o resultado exibido é: 
A. [1, 2, 3, 4, 5, 6, 7, 8] 
B. [8] 
C. [ ] 
D. [8, 7, 6, 5, 4, 3, 2, 1] 
A impressão da sequência L com a chamada L[::-1] é feita percorrendo toda a sequência L, em sentido inverso. 
Considerações finais 
Neste tema, você conheceu as principais características da linguagem Python e alguns conceitos 
relativos ao uso de variáveis, bem como aspectos concernentes à vinculação, como tempo e ambientes. 
Além disso, viu o conceito de escopo de visibilidade, tanto estático como dinâmico. 
Nos módulos, foi feita uma referência a tipos de dados, como int, float ou string. Você estudou ainda 
as formas de atribuição, além de ter escrito seu primeiro programa em Python, utilizando o que aprendeu e, 
também, as formas de entrada e saída de dados que a linguagem oferece. 
O uso correto desses conceitos é essencial na sua jornada de formação como programador. 
Recomendamos que fique atento aos detalhes e procure sempre programar de forma organizada. Isso vai 
evitar erros bobos e tornar sua experiência mais agradável. 
Referências 
BELANI, G. Programming Languages You Should Learn in 2020. Consultado em meio eletrônico em: 
26 mai. 2020. 
PERKOVIC, L. Introdução à computação usando Python: um foco no desenvolvimento de aplicações. 
Rio de Janeiro: LTC, 2016. 
PYCHARM. The Python IDE for Professional Developers. Consultado em meio eletrônico em: 15 jun. 
2020. 
PYTHON. PEP 0 – Index of Python Enhancement Proposals (PEPs). Consultado em meio eletrônico 
em: 2 jun. 2020. 
PYTHON. Fractions – Rational Number. Consultado em meio eletrônico em: 16 jun. 2020. 
PYTHON. Math – Mathematical Functions. Consultado em meio eletrônico em: 16 jun. 2020. 
Explore+ 
Se você quiser ter mais exercícios para treinar e desafios mais complexos, recomendamos a visita 
ao site da Python Brasil. 
Como vimos, dentre as PEPs, destaca-se a PEP8, que estabelece um guia de estilo de programação. 
Sugerimos que você pesquise mais sobre isso. 
Para mais funções matemáticas, você pode utilizar os módulos matemáticos mathe fractions. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 70 
 
Python Estruturado 
Introdução 
Programar significa, como em qualquer disciplina, aprender ferramentas que permitam desenvolver 
melhor a sua atividade. Ao aprender os conceitos básicos de programação, o estudante desenvolve 
habilidades iniciais para escrever seus primeiros programas. Porém, é difícil imaginar que aplicações 
profissionais sejam feitas totalmente baseadas apenas nesses conceitos básicos. 
Ao pensarmos em aplicações mais complexas, é essencial considerar a necessidade de ganhar 
tempo, com o computador executando as tarefas repetitivas, e as demandas de manutenção e tratamento 
de erros. Para avançar no aprendizado da programação, você conhecerá novas ferramentas, entre elas as 
estruturas de controle, como decisão e repetição, além dos subprogramas e bibliotecas, bem como as 
formas de tratar exceções e eventos. 
Vamos começar nossa jornada acessando os códigos-fontes originais propostos para o aprendizado 
de Python estruturado. Baixe o arquivo aqui, descompactando-o em seu dispositivo. Assim, você poderá 
utilizar os códigos como material de apoio ao longo do tema! 
Estruturas de decisão e repetição em Python 
As estruturas de controle permitem selecionar quais partes do código serão executadas – chamadas 
de estruturas de decisão – e repetir blocos de instruções com base em algum critério, como uma variável de 
controle ou a validade de alguma condição – chamadas de estruturas de repetição. Neste módulo, vamos 
conhecer as estruturas de decisão e de repetição em Python. 
Tratamento das condições 
As estruturas de decisão e de repetição possuem sintaxes bastante semelhantes em C e em Python. 
Mesmo com essa grande semelhança, existe uma diferença crítica no tratamento das condições. 
Diferentemente da linguagem C, Python oferece o tipo bool. Por isso, cabe ressaltar a diferença de 
comportamento das duas linguagens nesse tratamento. 
Python C 
Existe o tipo bool Não existe o tipo bool 
True Qualquer valor diferente de 0 (zero) 
False 0 (zero) ou vazio 
Atenção 
Observe que o fato de haver o tipo bool em Python permite que as condições sejam tratadas como verdadeiras 
ou falsas, o que não é exatamente igual em C. 
As Estruturas de decisão If, If-Else E Elif 
Em Python, é possível utilizar as estruturas de decisão if e if-else da mesma forma que em C. A 
diferença principal é o modo de delimitar os blocos de instruções relativos a cada parte da estrutura. Observe 
a Tabela 2 e a Tabela 3: 
Python C 
if <condição>: if <condição>{ 
 Instruções com 4 espaços de indentação A indentação não é exigida 
Instrução fora do if } 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 71 
 
Python C 
if <condição>: if <condição>{ 
 Instruções com 4 espaços de indentação (caso a condição seja verdadeira) Bloco 1 (caso a condição seja verdadeira). A indentação não é exigida 
else: } else { 
 Instruções com 4 espaços de indentação (caso a condição seja falsa) Bloco 2 (caso a condição seja falsa). A indentação não é exigida 
Instrução fora do if } 
 
Python também oferece a estrutura elif, que permite o teste de duas condições de forma sequencial. 
Essa estrutura não existe em C, sendo necessário o encadeamento de estruturas if-else. Em geral, o formato 
da estrutura elif é: 
if <condição 1>: 
 Bloco de código que será executado caso condição seja True 
elif <condição 2>: 
 Bloco de código que será executado caso condição 1 seja False e condição 2 seja True 
else: 
 Bloco de código que será executado caso condição 1 seja False e condição 2 seja False 
Instrução fora do if 
 
Veja uma implementação possível com a estrutura elif na Figura 1: 
idade = eval(input('Informe a idade da criança: ')) 
if idade < 5: 
print('A criança deve ser vacinada contra a gripe.') 
print('Procure o posto de saúde mais próximo.') 
elif idade == 5: 
print('A vacina estará disponível em breve.') 
print('Aguarde as próximas informações.') 
else: 
print('A vacinação só ocorrerá daqui a 3 meses.') 
print('Informe-se novamente neste prazo.') 
print('Cuide da saúde sempre. Até a próxima.') 
 
Perceba que a indentação precisa ser ajustada, uma vez que o último else é relativo ao elif. 
Por isso, eles precisam estar alinhados. 
Estrutura de repetição for 
A estrutura de repetição for tem funcionamento muito semelhante nas linguagens C e Python. Porém, 
a sintaxe é diferente nas duas linguagens. Além disso, em Python existe maior flexibilidade, já que a 
repetição pode ser controlada por uma variável não numérica. 
Antes de detalhar o for, vamos conhecer uma função de Python que gera uma lista de valores 
numéricos. Essa lista ajudará a verificar a repetição e deixará mais claro o entendimento do laço. 
As listas do tipo range() 
Ao chamar o método range(), Python cria uma sequência de números inteiros, de maneira simples à 
mais complexa. Veja a seguir: 
Simples 
Ela pode ser chamada de maneira simples, apenas com um argumento. Nesse caso, a sequência 
começará em 0 e será incrementada de uma unidade até o limite do parâmetro passado (exclusive). 
Por exemplo: range(3) cria a sequência (0, 1, 2). 
Não iniciadas em 0 
Para que a sequência não comece em 0, podemos informar o início e o fim como parâmetros, 
lembrando que o parâmetro fim não entra na lista (exclusive o fim). O padrão é incrementar cada 
termo em uma unidade. Ou seja, a chamada range(2, 7) cria a sequência (2, 3, 4, 5, 6). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 72 
 
Indicando início, fim e passo 
Também é possível criar sequências mais complexas, indicando os parâmetros de início, fim e 
passo, nessa ordem. O passo é o valor que será incrementado de um termo para o próximo. 
Por exemplo, range(2, 9, 3) cria a sequência (2, 5, 8). 
A sintaxe da estrutura for 
A estrutura for tem a seguinte sintaxe em Python: 
for <variável> in <sequência>: 
Bloco que será repetido para todos os itens da sequência 
Instrução fora do for 
 
Cabe ressaltar a diferença de sintaxe entre as linguagens C e Python. Veja a Tabela 4: 
Python C 
for <variável> in <sequência>: for (inicialização; condição; incremento ou decremento){ 
 Instruções com 4 espaços de indentação Bloco de instruções a ser repetido. A indentação não é exigida 
Instrução fora do for } 
 
Vamos analisar um exemplo simples em Python: imprimir todos os elementos de uma sequência 
criada com a chamada range(). Veja uma possível implementação desse exemplo na Figura 2: 
for item in range(2, 9, 3): 
print(item) 
 sequência 2 5 8 
Iteração 1 do laço item = 2 
 
Iteração 2 do laço item = 
 
5 
 
Iteração 3 do laço item = 
 
8 
 
O laço for com uma string 
Python também permite que a repetição aconteça ao longo de uma string. Para isso, basta lembrar 
que a string é uma sequência de caracteres individuais. Suponha que você queira soletrar o nome informado 
pelo usuário. Uma possível implementação está na Figura 3: 
nome = input("Entre com seu nome: ") 
for letra in nome: 
print(letra) 
A linha 1 faz com que a palavra inserida pelo usuário seja armazenada na variável nome; 
A linha 2 mostra a criação do laço, com a variável letra percorrendo a sequência de caracteres 
armazenada na variável nome; 
A linha 3 indica a instrução que será executada para cada repetição desse laço. O laço for executa 
a instrução da linha 3 tantas vezes quantos forem os elementos da sequência que está na variável 
nome. 
Veja um exemplo de execução na Figura 4: 
Entre com o seu nome: Laura 
L 
a 
u 
r 
a 
Uso do laço for com qualquer sequência 
Até agora, estudamos o uso do laço for com iterações sobre strings e sobre sequências numéricas, 
mas Python permite ainda mais que isso! 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 73 
 
Podemos utilizar o laço for com iteraçõessobre qualquer sequência, não somente as numéricas e 
as strings. 
Observe o exemplo da Figura 5: 
nomes = ['Laura', 'Lis', 'Guilherme', 'Enzo', 'Arthur'] 
for nome in nomes: 
print(nome) 
Veja o resultado da execução na Figura 6: 
Laura 
Lis 
Guilherme 
Enzo 
Arthur 
Estrutura de repetição while 
A estrutura de repetição while tem funcionamento e sintaxe muito semelhantes nas linguagens C e 
Python. Observe a comparação entre as duas linguagens na Tabela 6: 
Python C 
while <condição>: while <condição>{ 
 Instruções com 4 espaços de indentação Bloco de instruções a ser repetido. A indentação não é exigida 
Instrução fora do while } 
 
Como exemplo inicial do uso do laço while, vamos analisar um programa em que o usuário precisa 
digitar a palavra “sair” para que o laço while seja encerrado. 
Uma possível implementação desse exemplo em Python está na Figura 7: 
palavra = input('Entre com uma palavra: ') 
while palavra != 'sair': 
palavra = input('Digite sair para encerrar o laço: ') 
print('Você digitou sair e agora está fora do laço') 
 
A linha 1 representa a solicitação ao usuário para que ele insira uma palavra, que será armazenada 
na variável palavra; 
A linha 2 cria o laço while, que depende da condição <valor da variável palavra ser diferente de 
‘sair’>; 
A linha 3 será repetida enquanto a condição for verdadeira, ou seja, enquanto o valor da variável 
palavra for diferente de ‘sair’. Quando esses valores forem iguais, a condição do laço while será 
falsa e o laço será encerrado; 
A linha 4 representa a impressão da mensagem fora do laço while. 
Veja uma execução desse programa na Figura 8: 
Entre com uma palavra: teste 
Digite sair para encerrar o laço: Oi? 
Digite sair para encerrar o laço: Estou tentando... 
Digite sair para encerrar o laço: Aff... 
Digite sair para encerrar o laço: Blz, entendi... 
Digite sair para encerrar o laço: Sair 
Digite sair para encerrar o laço: Ah! o 'S' foi maiúsculo 
Digite sair para encerrar o laço: sair 
Você digitou sair e agora está fora do laço 
Observe agora outra execução do mesmo programa na Figura 9: 
Entre com uma palavra: sair 
Você digitou sair e agora está fora do laço 
Perceba que ao digitar ‘sair’ logo na primeira solicitação, a linha 3 do nosso programa não é 
executada nenhuma vez. Ou seja, o programa nem chega a entrar no laço while. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 74 
 
Em C, existe outra estrutura muito semelhante ao while, chamada do-while. A diferença básica entre 
elas é o momento em que a condição é testada, como vemos a seguir: 
1. No laço while, a condição é testada antes da iteração. 
2. O laço while testa e executa caso a condição seja verdadeira. 
3. No laço do-while, a condição é testada após a iteração. 
4. O laço do-while executa e testa. 
Infelizmente, a estrutura do-while não existe em Python. Isso não chega a ser um grande problema, 
porque podemos adaptar nosso programa e controlar as repetições com o laço while. 
O laço while infinito 
Laços infinitos são úteis quando queremos executar um bloco de instruções indefinidamente. 
O laço while infinito tem o seguinte formato: 
while True: 
Bloco que será repetido indefinidamente 
Exemplo 
Suponha que você deseje criar uma aplicação que permaneça por meses ou anos sendo executada, 
registrando a temperatura ou a umidade de um ambiente. Logicamente, estamos supondo que você tenha essa 
informação disponível a partir da leitura de algum sensor. 
Deve-se tomar cuidado e ter certeza de que seu uso é realmente necessário para evitar problemas de consumo 
excessivo de memória. 
As instruções auxiliares break, continue e pass 
A instrução break 
A instrução break funciona da mesma maneira em C e em Python. Ela interrompe as repetições dos 
laços for e while. Quando a execução do programa chega a uma instrução break, a repetição é encerrada e 
o fluxo do programa segue a partir da primeira instrução seguinte ao laço. 
Para exemplificar o uso da instrução break, vamos voltar ao primeiro exemplo do laço while, utilizando 
o laço infinito. O laço será encerrado quando o usuário inserir a palavra ‘sair’. Veja a Figura 10: 
while True: 
palavra = input('Entre com uma palavra: ') 
if palavra == 'sair': 
break 
print('Você digitou sair e agora está fora do laço') 
 
Caso haja vários laços aninhados, o break será relativo ao laço em que estiver inserido. Veja a Figura 
11: 
while True: 
print('Você está no primeiro laço.') 
opcao1 = input('Deseja sair dele? Digite SIM para isso. ') 
if opcao1 == 'SIM': 
break # este break é do primeiro laço 
else: 
while True: 
print('Você está no segundo laço.') 
opcao2 = input('Deseja sair dele? Digite SIM para isso. ') 
if opcao2 == 'SIM': 
break # este break é do segundo laço 
print('Você saiu do segundo laço.') 
print('Você saiu do primeiro laço') 
 
A instrução continue 
A instrução continue também funciona da mesma maneira em C e em Python. Ela atua sobre as 
repetições dos laços for e while, como a instrução break, mas não interrompe todas as repetições do laço. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 75 
 
A instrução continue interrompe apenas a iteração corrente, fazendo com que o laço passe para a próxima 
iteração. 
O exemplo a seguir imprime todos os números inteiros de 1 até 10, pulando apenas o 5. Veja sua 
implementação na Figura 12: 
for num in range(1, 11): 
if num == 5: 
continue 
else: 
print(num) 
print('Laço encerrado') 
 
Para ressaltar a diferença entre as instruções break e continue, vamos alterar a linha 3 do nosso 
programa, trocando a instrução continue pela instrução break. Veja a nova execução na Figura 13: 
1 
2 
3 
4 
Laço encerrado 
 
A instrução pass 
A instrução pass atua sobre a estrutura if, permitindo que ela seja escrita sem outras instruções a 
serem executadas caso a condição seja verdadeira. Assim, podemos concentrar as instruções no caso em 
que a condição seja falsa. Suponha que queiramos imprimir somente os números ímpares entre 1 e 10. Uma 
implementação possível está na Figura 14: 
for num in range(1, 11): 
if num % 2 == 0: 
pass 
else: 
print(num) 
print('Laço encerrado') 
 
Veja a execução desse programa na Figura 15: 
1 
3 
5 
7 
9 
Laço encerrado 
Claramente, seria possível reescrever a condição do if-else para que pudéssemos transformá-lo em 
um if simples, sem else. Porém, o objetivo aqui é mostrar o uso da instrução pass. 
Agora que já vimos os principais conceitos relativos às estruturas de decisão e de repetição, vamos 
testar seus conhecimentos. 
Verificando o aprendizado 
1. Considere o seguinte trecho de um programa escrito em Python: 
s = 0 
for i in range(5): 
s += 3*i 
print(s) 
Assinale a opção que apresenta corretamente o que será impresso na tela. 
A. 0 3 9 18 30 
B. 0 3 6 9 12 
C. 30 
D. 45 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 76 
 
2. Considere o seguinte trecho de um programa escrito em Python: 
s = 0 
a = 1 
while s < 5: 
s = 3*a 
a += 1 
print(s) 
Assinale a opção que apresenta corretamente o que será impresso na tela. 
A. 9 
B. 3 6 
C. 3 3 
D. 3 6 9 12 
Principais conceitos de subprogramas e a sua utilização em Python 
Os subprogramas são elementos fundamentais dos programas e por isso são importantes no estudo 
de linguagens de programação. Neste módulo, abordaremos os conceitos de subprogramas, como 
características gerais, passagem de parâmetros e recursividade, além da utilização de subprogramas em 
Python. 
Características gerais dos subprogramas 
Todos os subprogramas estudados neste módulo, com base em Sebesta (2018), têm as seguintes 
características: 
1. Cada subprograma tem um único ponto de entrada. 
2. A unidade de programa chamadora é suspensa durante a execução do subprograma 
chamado, o que significa que existe apenas umsubprograma em execução em determinado 
momento. 
3. Quando a execução do subprograma termina, o controle sempre retorna para o chamador. 
 
Definições básicas 
As definições básicas, conforme Sebesta (2018), estabelecem que: 
1. Um subprograma é definido quando o desenvolvedor descreve a interface e as ações da 
abstração desse subprograma. 
2. O subprograma foi chamado quando uma instrução traz um pedido explícito para sua 
execução. 
3. O subprograma está ativo após o início de sua execução, a partir da sua chamada e 
enquanto ele não foi concluído. 
 
O cabeçalho do subprograma é a primeira parte da definição, em que podem ser especificados o 
nome, os parâmetros e o tipo de retorno do subprograma. 
Em C, o cabeçalho dos subprogramas – sendo chamados de funções – traz, em ordem: o tipo de 
retorno, o nome e a lista de parâmetros, como a seguir: 
float calculaIMC (int peso, float altura) 
Em Python, as funções definidas pelo desenvolvedor devem ser precedidas pela palavra reservada 
def. Não são especificados o tipo de retorno nem os tipos dos parâmetros, como no exemplo a seguir: 
def calculaIMC (peso, altura) 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 77 
 
Em Python, as sentenças de função def são executáveis. Isso implica que a função só pode ser 
chamada após a execução da sentença def. Veja o exemplo na Figura 16: 
escolha = input("Escolha uma opção de função: 1 ou 2") 
if escolha == 1: 
def func1(x): 
return x + 1 
else: 
def func2(x): 
return x + 2 
s = func1(10) 
print(s) 
A função func1() só pode ser chamada caso a variável escolha seja igual a 1. Ou seja, o usuário 
deverá inserir 1 quando solicitado (na linha 1), para que a linha 9 possa ser executada sem que seja gerado 
um erro. 
Parâmetros 
Usualmente, um subprograma executa cálculos e operações a partir de dados que ele deve 
processar. Existem duas maneiras de o subprograma obter esses dados: acessando variáveis não locais, 
mas visíveis para o subprograma, ou pela passagem de parâmetros. 
Quando o subprograma recebe os parâmetros adequados, ele pode ser executado com quaisquer 
valores recebidos. Porém, quando ele manipula variáveis não locais, uma forma de evitar alterações 
indevidas nessas variáveis é fazendo cópias locais delas. De acordo com Sebesta (2018), o acesso 
sistemático a variáveis não locais pode diminuir a confiabilidade do programa. 
São denominados parâmetros formais aqueles do cabeçalho do subprograma. 
Quando o subprograma é chamado, é necessário escrever o nome do subprograma e a lista de 
parâmetros a serem vinculados aos parâmetros formais dele, que são denominados parâmetros reais ou 
argumentos. 
No exemplo da Figura 16, existe o cabeçalho da função func1 na linha 3, com o parâmetro formal x. 
Na linha 9, a função func1 é chamada com o parâmetro real 10. 
Em Python, é possível estabelecer valores padrão para os parâmetros formais. O valor padrão é 
usado quando a chamada da função ocorre sem nenhum parâmetro real. Veja o exemplo de definição e 
chamada da função taxímetro na Figura 17: 
def taximetro(distancia, multiplicador=1): 
largada = 3 
km_rodado = 2 
valor = (largada + distancia * km_rodado) * multiplicador 
return valor 
 
 
pagamento = taximetro(3.5) 
print(pagamento) 
 
Observe que mesmo com a definição da linha 1 de dois parâmetros formais, a chamada da função 
na linha 8 ocorre apenas com um parâmetro real. 
A palavra reservada return indica que a função retorna algum valor. Isso implica que o valor 
retornado seja armazenado em uma variável do programa chamador (como ocorre na linha 8), ou utilizado 
como parâmetro para outra função. 
Atenção 
Retornar um valor é diferente de imprimir na tela. Ao utilizar a função print(), ocorre apenas a impressão de 
algo na tela, o que não significa que tenha havido retorno de qualquer função definida pelo usuário. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 78 
 
Procedimentos e funções 
Os subprogramas podem ser, distintamente, procedimentos e funções. De acordo com Sebesta 
(2018): 
Procedimentos → São aqueles que não retornam valores. 
Funções → São aquelas que retornam valores. 
 
Na maioria das linguagens que não explicita a diferença entre eles, as funções podem ser definidas 
sem retornar qualquer valor, tendo comportamento de procedimento. Esse é o caso de Python. Veja o 
exemplo da Figura 18: 
def func1(x): 
x = 10 
print(f'Função func1 - x = {x}') 
 
 
def func2(x): 
x = 20 
print(f'Função func2 - x = {x}') 
 
 
x = 0 
func1(x) 
func2(x) 
print(f'Programa principal - x = {x}') 
 
As funções func1(x) e func2(x) não possuem qualquer retorno. Ou seja, são funções com 
comportamento de procedimentos. 
Ambientes de referenciamento local 
Variáveis locais 
Quando um subprograma define suas próprias variáveis, estabelece ambientes de referenciamento 
local. Essas variáveis são chamadas de variáveis locais, com seu escopo usualmente sendo o corpo do 
subprograma. As variáveis locais podem ser: 
Dinâmicas da pilha 
São vinculadas ao armazenamento no início da execução do subprograma e desvinculadas quando 
essa execução termina. As variáveis locais dinâmicas da pilha têm diversas vantagens, e a principal 
delas é a flexibilidade. Suas principais desvantagens são o custo do tempo – para alocar, inicializar 
(quando necessário) e liberar tais variáveis para cada chamada ao subprograma – e o fato de que 
os acessos a essas variáveis locais devem ser indiretos, enquanto os acessos às variáveis estáticas 
podem ser diretos. 
Estáticas 
São vinculadas a células de memória antes do início da execução de um programa e permanecem 
vinculadas a essas mesmas células até que a execução do programa termine. Elas são um pouco 
mais eficientes que as variáveis locais dinâmicas da pilha, já que não é necessário tempo para 
alocar ou liberar essas variáveis. Sua maior desvantagem é a incapacidade de suportar recursão, 
como vai ser explicado adiante. 
Atenção 
Nas linguagens C e C++, as variáveis locais são dinâmicas da pilha, a menos que sejam especificamente 
declaradas como static. Todas as variáveis locais em Python são dinâmicas da pilha. As variáveis globais são 
declaradas em definições de método, e qualquer variável declarada global em um método precisa ser definida fora 
dele. Caso haja uma atribuição à variável local com mesmo nome de uma variável global, esta é implicitamente 
declarada como local. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 79 
 
Voltando ao exemplo da Figura 18, vamos detalhar as funções func1(x) e func2(x): 
As linhas 1, 2 e 3 definem a função func1(x), que recebe o parâmetro x, mas tem uma variável local 
de nome x, cujo valor atribuído é 10; 
Analogamente, a função func2(x) – definida nas linhas 6, 7 e 8 – que recebe o parâmetro x e tem 
uma variável de mesmo nome, mas com valor atribuído 20; 
O programa principal tem uma variável global de mesmo nome x, cujo valor atribuído é 0, na linha 
11; 
Veja que as chamadas às funções func1(x) e func2(x) ocorrem nas linhas 12 e 13, quando a variável 
x global já recebeu o valor 0. Porém, ao serem executadas, cada uma dessas funções tem a sua própria 
variável local, a quem todas as referências internas são feitas. 
Confira a execução desse exemplo: 
Função func1 - x = 10 
Função func2 - x = 20 
Programa principal - x = 0 
 
Mesmo com a variável global tendo valor nulo, cada variável local das funções func1(x) e func2(x) 
tem seu próprio valor, e não ocorrem alterações na variável global mesmo com as atribuições das linhas 2 
e 7. 
Para alterar a variável global x, seria necessário explicitar dentro de cada função que o nome x é 
referente a ela. Isso pode ser feito com a palavra reservada global. Além de explicitar a referência à variável 
global, as funções func1(x) e func2(x) não recebem mais os parâmetros de mesmo nome, já que fazemreferência à variável global. Veja como ficaria o nosso exemplo com essa pequena alteração na Figura 20: 
def func1(): 
global x 
x = 10 
print(f'Função func1 - x = {x}') 
 
 
def func2(): 
global x 
x = 20 
print(f'Função func2 - x = {x}') 
 
 
x = 0 
func1() 
func2() 
print(f'Programa principal - x = {x}') 
 
 
Observe agora a execução desse exemplo alterado: 
Função func1 - x = 10 
Função func2 - x = 20 
Programa principal - x = 20 
 
Percebe-se que o print() do programa principal está na linha 16, depois da chamada à função 
func2(x). Dessa forma, a variável global x foi alterada na execução da func2(x) e fica com o valor 20 quando 
a execução volta ao programa principal. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 80 
 
Subprogramas aninhados 
Em Python, e na maioria das linguagens funcionais, é permitido aninhar subprogramas. Porém, as 
linguagens C e C++ não permitem essa prática. Veja o exemplo: 
def taximetro(distancia):: 
def calculaMult(): 
if distancia < 5: 
return 1.2 
else: 
return 1 
multiplicador = calculaMult() 
largada = 3 
km_rodado = 2 
valor = (largada + distancia * km_rodado) * multiplicador 
return valor 
 
dist = eval(input("Entre com a distancia a ser percorrida em km: ")) 
pagamento = taximetro(dist) 
print(f'O valor a pagar é R$ {pagamento}') 
 
A função taximetro() tem, dentro de sua definição, a definição de outra função denominada 
calculaMult(). Na linha 7, a função calculaMult() é chamada e o seu retorno é armazenado na variável 
multiplicador. 
Métodos de passagens de parâmetros 
Os métodos de passagem de parâmetros são as maneiras que existem para transmiti-los ou recebê-
los dos subprogramas chamados. Os parâmetros podem ser passados principalmente por: 
Valor 
O parâmetro formal funciona como uma variável local do subprograma, sendo inicializado com o 
valor do parâmetro real. Dessa maneira, não ocorre alteração na variável externa ao subprograma, 
caso ela seja passada como parâmetro. 
Referência 
Em vez de passar o valor do parâmetro real, é transmitido um caminho de acesso (normalmente 
um endereço) para o subprograma chamado. Isso fornece o caminho de acesso para a célula que 
armazena o parâmetro real. Assim, o subprograma chamado pode acessar o parâmetro real na 
unidade de programa chamadora. 
Saiba mais 
Na linguagem C, utilizamos ponteiros para fazer a passagem de parâmetros por referência. As transmissões 
de parâmetros que não sejam ponteiros utilizam a passagem por valor. 
O método de passagem de parâmetros de Python é chamado passagem por atribuição. Como 
todos os valores de dados são objetos, toda variável é uma referência para um objeto. Ao se estudar 
orientação a objetos, fica mais clara a diferença entre a passagem por atribuição e a passagem por 
referência. Por enquanto, podemos entender que a passagem por atribuição é uma passagem por 
referência, pois os valores de todos os parâmetros reais são referências. 
Recursividade 
Uma função recursiva é aquela que chama a si mesma. Veja o exemplo da função regressiva(), como 
mostrado na Figura 23: 
def regressiva(x): 
print(x) 
regressiva(x - 1) 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 81 
 
Na implementação da função regressiva(), tendo x como parâmetro, ela própria é chamada com o 
parâmetro x – 1. Vamos analisar a chamada regressiva(2): 
1. Ao chamar regressiva(2), o valor 2 é exibido na tela pela linha 2, e ocorre uma nova chamada 
da função regressiva() na linha 3, com o parâmetro 1. Vamos continuar com esse caminho 
de execução da regressiva(1). 
2. Ao chamar regressiva(1), o valor 1 é exibido na tela pela linha 2, e ocorre uma nova chamada 
da função regressiva() na linha 3, com o parâmetro 0. 
3. Ao chamar regressiva(0), o valor 0 é exibido na tela e ocorre uma nova chamada da função 
regressiva, com o parâmetro -1, e assim sucessivamente. 
Atenção 
Conceitualmente, essa execução será repetida indefinidamente até que haja algum erro por falta de memória. 
Perceba que não definimos adequadamente uma condição de parada para a função regressiva(), o que leva a esse 
comportamento ruim. 
Em Python, o interpretador pode interromper a execução indefinida, mas essa não é uma boa prática. 
Uma forma de contornar esse problema é definir adequadamente uma condição de parada, como no 
exemplo da Figura 24: 
def regressiva(x): 
if x <= 0: 
print("Acabou") 
else: 
print(x) 
regressiva(x-1) 
 
Uma função recursiva que termina tem: 
1. Um ou mais casos básicos, que funcionam como condição de parada da recursão. 
2. Uma ou mais chamadas recursivas, que têm como parâmetros valores mais próximos do(s) 
caso(s) básico(s) do que o ponto de entrada da função. 
Alguns exemplos clássicos de funções que podem ser implementadas de forma recursiva são o 
cálculo do fatorial de um inteiro não negativo e a sequência de Fibonacci, que serão explorados a seguir. 
A função recursiva fatorial 
A função matemática fatorial de um inteiro não negativo n é calculada por: 
 
Fonte: Estácio de Sá 
Além disso, ela pode ser definida recursivamente por: 
 
Fonte: Estácio de Sá 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 82 
 
Uma implementação recursiva da função fatorial em Python está na Figura 25: 
def fatorial(n): 
if n == 0 or n == 1: 
return 1 
else: 
return n*fatorial(n-1) 
 
Vale ressaltar que a função fatorial também poderia ter sido implementada de forma não recursiva, 
como mostrado na Figura 26: 
def fatorial(n): 
fat = 1 
if n == 0 or n == 1: 
return fat 
else: 
for x in range(2, n + 1): 
fat = fat*x 
return fat 
 
Porém, neste tópico, o intuito principal é explorar a recursividade. 
A sequência de Fibonacci 
A sequência de Fibonacci é: 1, 1, 2, 3, 5, 8, 13, 21... Os dois primeiros termos são 1 e, a partir do 3º 
termo, cada termo é a soma dos dois anteriores. 
Uma possível implementação recursiva de função que determina o n-ésimo termo da sequência de 
Fibonacci está na Figura 27: 
def fibo(n): 
if n == 1 or n == 2: 
return 1 
else: 
return fibo(n - 1) + fibo(n - 2) 
 
A linha 2 traz as condições de parada. 
A linha 5 traz as chamadas recursivas para calcular os dois termos anteriores da sequência. 
Docstrings 
Em Python, é possível definir uma string que serve como documentação de funções definidas pelo 
desenvolvedor. Ao chamar o utilitário help() passando como parâmetro a função desejada, essa string é 
exibida. Veja a Figura 28 e a Figura 29: 
def fibo(n): 
'Determina o n-ésimo termo da sequência de Fibonacci' 
if n == 1 or n == 2: 
return 1 
else: 
return fibo(n - 1) + fibo(n - 2) 
 
print(help(fibo)) 
****************************************************************************************************** 
 
fibo(n) 
Determina o n-ésimo termo da sequência de Fibonacci 
Na Figura 28, a linha 2 mostra a declaração da docstring. 
A linha 8 mostra a impressão na tela da chamada help(fibo). Na Figura 29, está o resultado da 
execução desse programa. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 83 
 
Verificando o aprendizado 
1. Considere o seguinte trecho de um programa escrito em Python: 
def func1(x): 
x = 10 
print(x) 
 
x = 0 
print(x) 
func1(x) 
print(x) 
O que acontecerá quando o usuário tentar executar esse programa? 
A. Ocorrerá um erro e o programa não será executado. 
B. Ocorrerá um erro durante a execução. 
C. Será impresso na tela: 0 10 0 
D. Será impresso na tela: 0 10 10 
2. Considere o seguinte trecho de um programa, com uma implementação de função recursiva, escrito em 
Python: 
def rec(n): 
if n < 2: 
return rec(n - 1) 
 
print(rec(1)) 
Quando o usuário tentou executar esse programa, houve um erro. Qual é a causa? 
A. Na linha 2, o if está escrito de maneira errada. 
B. A função não tem condição de parada. 
C. A função estásem retorno. 
D. A função não poderia ter sido definida com uma chamada a ela própria. 
Uso correto de recursos de bibliotecas em Python 
Python oferece, em seu núcleo, algumas funções que já utilizamos, como print() e input(), além de 
classes como int, float e str. Logicamente, o núcleo da linguagem Python disponibiliza muitas outras funções 
(ou métodos) e classes além das citadas. Mas, ainda assim, ele é pequeno, com objetivo de simplificar o 
uso e ganhar eficiência. Para aumentar a disponibilidade de funções, métodos e classes, o desenvolvedor 
pode usar a biblioteca padrão Python. Neste módulo, apresentaremos alguns dos principais recursos dessa 
biblioteca e a forma de utilizá-los. 
Biblioteca padrão python 
A biblioteca padrão Python consiste em milhares de funções, métodos e classes relacionados a 
determinada finalidade e organizados em componentes chamados módulos. São mais de 200 módulos que 
dão suporte, entre outras coisas, a: 
• Operações matemáticas. 
• Interface gráfica com o usuário (GUI). 
• Funções matemáticas e geração de números pseudoaleatórios. 
Atenção 
É importante lembrar dos conceitos de classes e objetos, pois eles são os principais conceitos do paradigma 
de programação orientada a objeto. As classes são fábricas, que podem gerar instâncias chamadas objetos. Uma 
classe Pessoa, por exemplo, pode ter como atributos nome e CPF. Ao gerar uma instância de Pessoa, com nome João 
da Silva e CPF 000.000.000-00, temos um objeto. 
Saiba mais 
Para melhor compreensão dos conceitos de classe e objeto, pesquise sobre paradigma orientado a objeto. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 84 
 
Como usar uma função de módulo importado 
Para usar as funções e os métodos de um módulo, são necessários dois passos: 
Fazer a importação do módulo desejado com a instrução: 
import nome_modulo 
Chamar a função desejada, precedida do nome do módulo, com a instrução: 
nome_modulo.nome_funcao(paramêtros) 
Como exemplo, vamos importar o módulo math (dedicado a operações matemáticas) e calcular a 
raiz quadrada de 5, por meio da função sqrt(). Observe a Figura 30: 
>>> import math 
>>> math.sqrt(5) 
2.23606797749979 
A partir desse ponto, serão apresentados os principais aspectos dos seguintes módulos: 
math → usado para operações matemáticas. 
random → usado para gerar números pseudoaleatórios. 
smtplib →usado para permitir envio de e-mails. 
time → usado para implementar contadores temporais. 
tkinter → usado para desenvolver interfaces gráficas. 
Módulo math 
Esse módulo provê acesso à funções matemáticas de argumentos reais. As funções não podem ser 
usadas com números complexos. 
O módulo math tem as funções listadas na Tabela 7, entre outras: 
Função Retorno 
sqrt(x) Raiz quadrada de x 
ceil(x) Menor inteiro maior ou igual a x 
floor(x) Maior inteiro menor ou igual a x 
cos(x) Cosseno de x 
sin(x) Seno de x 
log(x, b) Logaritmo de x na base b 
pi Valor de Pi (3.141592...) 
e Valor de e (2.718281...) 
Saiba mais 
Para mais informações sobre o módulo math, visite a biblioteca Python. 
Módulo random 
Esse módulo implementa geradores de números pseudoaleatórios para várias distribuições. 
Números inteiros 
• Para inteiros, existe: 
o Uma seleção uniforme a partir de um intervalo. 
Sequências 
• Para sequências, existem: 
o Uma seleção uniforme de um elemento aleatório; 
o Uma função para gerar uma permutação aleatória das posições na lista; 
o Uma função para escolher aleatoriamente sem substituição. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 85 
 
Distribuições de valores reais 
A Tabela 8 mostra algumas das principais funções disponíveis para distribuições de valores reais no 
módulo random. 
Função Retorno 
random() Número de ponto flutuante no intervalo [0.0, 1.0) 
uniform(a, b) Número de ponto flutuante N tal que a ≤ N ≤ b 
gauss(mu, sigma) Distribuição gaussiana. mu é a média e sigma é o 
desvio padrão. 
normalvariate(mu, sigma) Distribuição normal. mu é a média e sigma é o 
desvio padrão. 
 
Funções para números inteiros 
A Tabela 9 mostra algumas das principais funções disponíveis para inteiros no módulo random. 
Função Retorno 
randrange(stop) Um elemento selecionado aleatório de range(start, stop, step), mas sem construir um objeto range. 
randrange(start, stop [,step]) 
randint(a, b) Número inteiro N tal que a ≤ N ≤ b 
 
Funções para sequências 
A Tabela 10 mostra algumas das principais funções disponíveis para sequências no módulo random. 
Função Retorno 
choice(seq) Elemento aleatório de uma sequência não vazia seq. 
shuffle(x[, random]) Embaralha a sequência x no lugar. 
sample(pop, k) 
Uma sequência de tamanho k de elementos escolhidos da população pop, sem 
repetição. Usada para amostragem sem substituição. 
 
Saiba mais 
Para mais informações sobre o módulo random, visite a biblioteca Python. 
Módulo smtplib 
Esse módulo define um objeto de sessão do cliente SMTP que pode ser usado para enviar e-mail 
para qualquer máquina da internet com um serviço de processamento SMTP ou ESMTP. O exemplo a seguir 
vai permitir que você envie um e-mail a partir do servidor SMTP do Gmail. 
Como a Google não permite, por padrão, realizar o login com a utilização do smtplib por considerar 
esse tipo de conexão mais arriscada, será necessário alterar uma configuração de segurança. Para resolver 
isso, siga as instruções a seguir: 
1. Acesse sua conta no Google. 
2. Depois Segurança. 
3. Acesso a app menos seguro. 
4. Mude para "ativada" a opção de "Permitir aplicativos menos seguros". 
Para fazer seu primeiro envio, crie um programa novo no seu projeto. A Figura 31 mostra as 
importações necessárias para o envio: 
#import dos pacotes necessários 
from email.mime.multipart import MIMEMultipart 
from email.mime.text import MIMEText 
import smtplib 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 86 
 
A Figura 32 mostra a criação da mensagem, com o corpo e seus parâmetros. 
6 #criação de um objeto de mensagem 
7 msg = MIMEMultipart() 
8 texto = "Estou enviando um email com Python" 
9 
10 #parâmetros 
11 senha = "SUA SENHA" 
12 msg['From'] = "SEU E-MAIL" 
13 msg['To'] = "E-MAIL DESTINO" 
14 msg['Subject'] = "ASSUNTO" 
15 
16 #criação do corpo da mensagem 
17 msg.attach(MIMEText(texto, 'plain')) 
 
A linha 7 mostra a criação de um objeto de mensagem. 
A linha 8 mostra o corpo da mensagem em uma string. 
As linhas de 11 a 14 devem ser preenchidas com os valores adequados para que seu programa 
seja executado com sucesso. 
A linha 17 anexa o corpo da mensagem (que estava em uma string) ao objeto msg. 
A Figura 33 mostra os passos necessários para o envio em si. 
19 #criação do servidor 
20 server = smtplib.SMTP('smtp.gmail.com: 587') 
21 server.starttls() 
22 
23 #Login na conta para envio 
24 server.login(msg['From'], senha) 
25 
26 #envio da mensagem 
27 server.sendmail(msg['From'], msg['To'], msg.as_string()) 
28 
29 #encerramento do servidor 
30 server.quit() 
31 
32 print('Mensagem enviada com sucesso') 
33 
As linhas 20 e 21 mostram a criação do servidor e a sua conexão no modo TLS. 
A linha 24 mostra o login na conta de origem do e-mail. 
A linha 27 representa o envio propriamente dito. 
A linha 30 mostra o encerramento do servidor. 
Saiba mais 
Para mais informações sobre o módulo smtplib, visite a biblioteca Python. 
Módulo time 
Esse módulo provê diversas funções relacionadas a tempo. Também pode ser útil conhecer os 
módulos datetime e calendar. A Tabela 11 mostra algumas das principais funções disponíveis no módulo 
time. 
Função Retorno 
time() 
Número de segundos passados desde o início da contagem (epoch). Por padrão, o início é 00:00:00 do dia 1 de 
janeiro de 1970. 
ctime(segundos) Uma string representando o horário local, calculado a partir do número de segundos passado como parâmetro. 
gmtime(segundos) Converteo número de segundos em um objeto struct_time descrito a seguir. 
localtime(segundos) Semelhante à gmtime(), mas converte para o horário local. 
sleep(segundos) A função suspende a execução por determinado número de segundos. 
 
A Figura 34 mostra um exemplo de chamada das funções time() e ctime(). 
>>> x = time.time() 
>>> print(f'Local time: {time.ctime(x)}') 
Local time: Tue Jun 30 23:38:55 2020 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 87 
 
A variável x recebe o número de segundos desde 00:00:00 de 01/01/1970 pela função time(). Ao 
executar ctime(x), o número de segundos armazenado em x é convertido em uma string, com o horário local. 
A classe time.struct_time gera objetos sequenciais com valor de tempo retornado pelas funções 
gmtime() e localtime(). São objetos com interface de tupla nomeada: os valores podem ser acessados pelo 
índice e pelo nome do atributo. Existem os seguintes valores que estão apresentados na Tabela 12: 
Índice Atributo Valores 
0 tm_year Por exemplo, 2020 
1 tm_mon range [1, 12] 
2 tm_mday range [1, 31] 
3 tm_hour range [0, 23] 
4 tm_min range [0, 59] 
5 tm_sec range [0, 61] 
6 tm_wday range [0, 6], Domingo é 0 
7 tm_yday range [1, 366] 
8 tm_isdst 0, 1 ou -1 
N/A tm_zone abreviação do nome da timezone 
 
Saiba mais 
Para mais informações sobre o módulo time, visite a biblioteca Python. 
Módulo tkinter 
O pacote tkinter é a interface Python padrão para o Tk GUI (interface gráfica com o usuário) toolkit. 
Na maioria dos casos, basta importar o próprio tkinter, mas diversos outros módulos estão disponíveis no 
pacote. A biblioteca tkinter permite a criação de janelas com elementos gráficos, como entrada de dados e 
botões, por exemplo. 
O exemplo a seguir vai permitir que você crie a primeira janela com alguns elementos. Para isso, crie 
um programa novo no seu projeto. A Figura 35 mostra a criação da sua primeira janela, ainda sem qualquer 
elemento gráfico. 
1 from tkinter import * 
2 
3 janelaPrincipal = Tk() 
4 janelaPrincipal.mainloop() 
 
A linha 1 mostra a importação de todos os elementos disponíveis em tkinter. O objeto janelaPrincipal 
é do tipo Tk. Um objeto Tk é um elemento que representa a janela GUI. Para que essa janela 
apareça, é necessário chamar o método mainloop(); 
Para exibir textos, vamos usar o elemento Label. A Figura 36 mostra as linhas 4 e 5, com a criação 
do elemento e o seu posicionamento. O tamanho padrão da janela é 200 X 200 pixels, com o canto 
superior esquerdo de coordenadas (0,0) e o canto inferior direito de coordenadas (200,200). 
1 from tkinter import * 
2 
3 janelaPrincipal = Tk() 
4 texto = Label(master = janelaPrincipal, text = "Minha janela exibida") 
5 texto.place(x = 50 y = 100) 
6 janelaPrincipal.mainloop() 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 88 
 
 
Fonte: Estácio de Sá 
Vamos agora incrementar um pouco essa janela. Para isso, vamos acrescentar uma imagem e um 
botão. A imagem precisa estar na mesma pasta do seu arquivo .py. 
1 def funcClicar():2 
3 def funcClicar(): 
4 print("Botão pressionado") 
5 
6 janelaPrincipal = Tk() 
7 texto = Label(master = janelaPrincipal, text = "Minha janela exibida") 
8 texto.pack() 
9 
10 pic = PhotoImage(file="logoEstacio.gif") 
11 logo = Label(master = janelaPrincipal, image = pic) 
12 logo.pack() 
13 
14 botao = Button(master = janelaPrincipal, text = 'Clique', command = funcClicar) 
15 botao.pack() 
16 
17 janelaPrincipal.mainloop() 
18 
Na Figura 38, temos a inserção do elemento de imagem e o botão. Nas linhas 10, 11 e 12, é feita 
a criação do objeto Label para conter a imagem e seu posicionamento. Observe que passamos a 
utilizar o método pack(), que coloca o elemento centralizado e posicionado o mais perto possível 
do topo, depois dos elementos posicionados anteriormente. 
O elemento botão é criado na linha 14, com os atributos text e command, que, respectivamente, 
são o texto exibido no corpo do botão e a função a ser executada quando o botão for clicado. 
Para o funcionamento correto do botão, precisamos definir a função funcClicar(), nas linhas 3 e 4. 
Essa função serve apenas para imprimir na tela a string “Botão pressionado”. 
 
Fonte: Estácio de Sá 
Botão pressionado 
Saiba mais 
Para mais informações sobre o tkinter, visite a biblioteca Python. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 89 
 
Usando pacotes externos 
Além dos módulos fornecidos de forma integrada pela biblioteca padrão do Python, a linguagem 
possui uma grande vantagem: sua característica open-source permite que qualquer desenvolvedor, com o 
conhecimento adequado, desenvolva sua própria biblioteca e os seus próprios módulos, que chamaremos 
a partir de agora de pacotes. 
Dica 
Veremos como criar módulos mais adiante neste conteúdo. 
Com um pacote pronto, o desenvolvedor pode disponibilizar esse material na internet, de forma que 
qualquer pessoa possa aproveitar o código implementado. Isso foi um dos fatores que fez com que o Python 
se tornasse uma das linguagens mais utilizadas no mundo atualmente. 
Como forma de facilitar a distribuição dos pacotes entre os usuários, existe um grupo dentro da 
comunidade Python que mantém o chamado Python Package Index, ou PyPI, que é um grande servidor no 
qual os desenvolvedores podem hospedar os seus pacotes, contendo bibliotecas e/ou módulos para que 
sejam baixados e instalados por outras pessoas. 
É possível acessar o PyPI através do pip, um programa que pode ser instalado juntamente com a 
distribuição do Python. Para isso, certifique-se de que a caixa “pip” está marcada durante a instalação, 
conforme ilustrado a seguir. 
 
Fonte: Estácio de Sá 
Dica 
Para verificar se a sua instalação Python incluiu o pip, procure pela pasta Scripts dentro do diretório de 
instalação que você escolheu para o Python. Dentro dessa pasta, localize o arquivo pip.exe. Caso não o encontre, 
pesquise sobre como instalar o pip. O mais recomendado é tentar reinstalar o Python, lembrando de marcar a opção 
de incluir o pip durante o processo de instalação. 
Além do pip, é necessário termos o endereço para acessar o pip dentro da variável de ambiente 
PATH. O processo de instalação do python também permite incluir automaticamente o Python no seu PATH, 
porém, caso não tenha feito isso, siga os passos abaixo: 
1. Clique na tecla do Windows e escreva “Editar as variáveis de ambiente para a sua conta”. 
2. Na janela que abrir, procure pela variável Path, selecione-a e clique no botão “Editar”. 
3. Clique no botão “Novo” e digite o endereço da sua instalação do Python (por exemplo, 
D:\Python). 
4. Clique no botão “Novo” uma segunda vez e digite o endereço da pasta Scripts dentro da sua 
instalação do Python (por exemplo, D:\Python\Scripts). 
5. Aperte Ok até fechar todas as janelas. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 90 
 
É importante que você se certifique de que a opção “Add Python to PATH” está marcada durante a 
instalação, como ilustrado a seguir. 
 
Fonte: Estácio de Sá 
Com essas etapas concluídas, já conseguimos instalar nossos pacotes externos! 
Atenção 
Quando estiver trabalhando com pacotes externos, é extremamente recomendado o uso de ambientes virtuais 
(em inglês virtual environments ou simplesmente virtualenvs). Esses ambientes isolam o projeto em que você está 
trabalhando, e uma das vantagens disso é que você consegue saber exatamente quais pacotes externos estão sendo 
usados no projeto. 
É possível usar pacotes externos sem o uso de ambientes virtuais, porém isso pode causar uma confusão caso 
você tenha vários projetos Python no seu computador. 
Pesquise mais sobre ambientes virtuais e configure um em cada projeto. Não é muito difícil e vai te ajudar a 
deixar o seu código mais profissional! 
Para instalar um pacote externo disponível no PyPI, basta abrir oseu terminal (clique no botão do 
Windows e digite “cmd” ou “prompt de comando”), ative o seu ambiente virtual (se você estiver usando um) 
e digite o seguinte comando: d: \Projects\exemplo_pacotes>pip install <nome_do_pacote> 
 
Fonte: Estácio de Sá 
Substitua <nome_do_pacote> pelo pacote que você deseja usar. Temos inúmeros pacotes prontos 
à nossa disposição. Cada pacote normalmente possui um site que apresenta a sua documentação, de forma 
similar à documentação oficial do Python. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 91 
 
Abaixo você encontra uma lista com alguns dos pacotes externos mais comuns e utilizados no 
mercado: 
Nome do módulo Para que serve? 
numpy Cálculos, operações matemáticas e simulações 
pandas Manipulação de dados 
scikit-learn Modelos de aprendizado de máquina 
matplotlib Visualização de dados 
requests Biblioteca de comandos de comunicação pelo protocolo HTTP 
flask Construção de aplicações web 
 
Dica 
Antes de começar o seu próprio módulo, é sempre recomendado pesquisar se o que você quer fazer já existe 
em algum pacote popular. Se existir, procure pela documentação e instale esse pacote. 
O uso de módulos oriundos de pacotes externos é idêntico ao uso dos módulos da biblioteca padrão, 
basta utilizar o import nome_do_modulo no seu código. 
Criação do próprio módulo 
Os desenvolvedores podem criar seus próprios módulos de forma a reutilizar as funções que já 
escreveram e organizar melhor seu trabalho. Para isso, basta criar um arquivo .py e escrever nele suas 
funções. É importante observar que o arquivo do módulo precisa estar na mesma pasta do arquivo para 
onde ele será importado. 
Verificando o aprendizado 
1. Sabemos que é possível importar módulos e chamar funções desses módulos em Python. Considere o 
módulo math, que oferece diversas funções matemáticas. Uma dessas funções é a ceil(x), que retorna o menor inteiro 
maior ou igual a x. Suponha que um estudante queira usar uma variável n, que recebe o valor 5.9, e em seguida 
imprimir na tela o menor inteiro maior ou igual a ela. 
 
1 import math 
2 n = 5.9 
3 print(ceil(n)) 
 
1 import math 
2 n = 5.9 
3 math.ceil(n) 
4 print(n) 
 
1 import math 
2 n = 5.9 
3 print(ceil.math(n)) 
 
1 import math 
2 n = 5.9 
3 print(math.ceil(n)) 
 
2. Sobre a linguagem Python e sua biblioteca padrão, é correto afirmar que: 
A. Só permite a utilização dos módulos contidos na biblioteca padrão Python. 
B. Tem o módulo de interface gráfica tkinter, que não permite a criação de janelas com botões. 
C. Tem módulo de interface de e-mails smtplib, que não permite envio de e-mails por servidores gratuitos. 
D. Tem módulo de operações matemáticas math, que não permite operações com números 
complexos. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 92 
 
Formas de tratamento de exceções e eventos em Python 
Até agora, consideramos que nossos programas tiveram seu fluxo de execução normal. Neste 
módulo, vamos analisar o que acontece quando o fluxo de execução é interrompido por uma exceção, além 
de controlar esse fluxo excepcional. 
Erros e exceções 
Dois tipos básicos de erros podem acontecer em um programa em Python. Os erros de sintaxe são 
aqueles que ocorrem devido ao formato incorreto de uma instrução. Esses erros são descobertos pelo 
componente do interpretador Python, chamado analisador ou parser. Veja exemplos na Figura 41 e na 
Figura 42: 
>>> print 'hello' 
File "<input>", line 1 
print 'hello' 
ˆ 
SyntaxError: Missing parenthesesin call to 'print'. Did you mean print('hello')? 
Figura 41 - Erro de sintaxe 1 - Fonte: O autor (2020) 
 
>>> lista = [1 ; 2 ; 4] 
File "<input>", line 1" 
lista = [1 ; 2 ; 4] 
ˆ 
SyntaxError: invalid sytax 
Figura 42 - Erro de sintaxe 2 - Fonte: O autor (2020) 
 
Além desses, existem os erros que ocorrem em tempo de execução do programa, que não são 
devidos a uma instrução escrita errada, mas sim ao fato de que o programa entrou em um estado indevido. 
Temos os exemplos: 
A divisão por 0. 
A tentativa de acessar um índice indevido em uma lista. 
Um nome de variável não atribuído. 
Um erro causado por tipos incorretos de operando. 
Em cada caso, quando o programa atinge um estado inválido, dizemos que o interpretador Python 
levanta uma exceção. Isso significa que é criado um objeto que contém as informações relevantes sobre o 
erro. A Tabela 13 traz alguns tipos comuns de exceção: 
Exceção Explicação 
KeyboardInterrupt Levantado quando o usuário pressiona CTRL + C, a combinação de interrupção. 
OverflowError Levantado quando uma expressão de ponto flutuante é avaliada como um valor muito grande. 
ZeroDivisionError Levantado quando se tenta dividir por 0. 
IOError Levantado quando uma operação de entrada/saída falha por um motivo relacionado a isso. 
IndexError Levantado quando um índice sequencial está fora do intervalo de índices válidos. 
NameError Levantado quando se tenta avaliar um identificador (nome) não atribuído. 
TypeError Levantado quando uma operação da função é aplicada a um objeto do tipo errado. 
ValueError Levantado quando a operação ou função tem um argumento com o tipo correto, mas valor incorreto. 
 
Em Python, as exceções são objetos. A classe Exception é derivada de BaseException, classe 
base de todas as classes de exceção. BaseException fornece alguns serviços úteis para todas as classes 
de exceção, mas normalmente não se torna uma subclasse diretamente. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 93 
 
Captura e manipulação de exceções 
Para evitar que os programas sejam interrompidos quando uma exceção for levantada, é possível 
planejar um comportamento alternativo. Assim, o programa não será interrompido e a exceção poderá ser 
tratada. Chamamos esse processo de captura da exceção. 
Vamos considerar um exemplo de programa que solicita ao usuário, com a função input(), um número 
inteiro. Embora essa função trate a entrada do usuário como string, é possível utilizá-la em conjunto com a 
função eval() para que os dados inseridos sejam avaliados como números. A Figura 43 mostra uma 
implementação simples desse exemplo. 
1 num = eval(input("Entre com um número inteiro: ")) 
2 print(num) 
Mas o que aconteceria se o usuário digitasse uma palavra em vez de números? 
Veja a Figura 44. 
Entre com um número inteiro: dez 
Traceback (most recent call last): 
File "C:/Users/Humberto/PycharmProjects/estacio_ead/excessoes.py", line 1, in <module> 
num = eval(input("Entrecom um número inteiro: ")) 
File "<string>, line 1, in <module> 
NameError: name 'dez'is not defined 
 
Veja que o programa foi encerrado com uma exceção sendo levantada. Uma forma de fazer a captura 
e a manipulação de exceções é usar o par de instruções try / except. 
O bloco try é executado primeiro, no qual devem ser inseridas as instruções do fluxo normal do 
programa. 
O bloco except somente será executado se houver o levantamento de alguma exceção. 
Isso permite que o fluxo de execução continue de maneira alternativa. A Figura 45 mostra uma 
implementação possível desse exemplo: 
1 try: 
2 num = eval(input("Entre com um número inteiro: ")) 
3 print(num) 
4 except: 
5 print("Entre com o valor numérico e não letras") 
 
A execução pode ser conferida na Figura 46: 
Entre com um número inteiro: dez 
Entre com valor numérico e não letras 
 
O formato padrão de uso do par try/except é: 
1 try: 
2 Bloco 1 
3 except: 
4 Bloco 2 
5 Instrução fora do try/except 
 
O bloco 1 representa o fluxo normal do programa. Caso uma exceção seja levantada, o bloco 2 será 
executado, permitindo o tratamento adequado dela. Esse bloco 2 é chamado de manipulador de exceção. 
Atenção 
Em Python, o manipulador de exceção padrão é quem executa o trabalho de captura da exceção caso não 
haja um tratamento explícito feito pelo desenvolvedor. É essemanipulador padrão o responsável pela exibição das 
mensagens de erro no console, como visto na Figura 44. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 94 
 
Captura de exceções de determinado tipo 
Python permite que o bloco relativo ao except só seja executado caso a exceção levantada seja de 
determinado tipo. Para isso, o except precisa trazer o tipo de exceção que se deseja capturar. A Figura 47 
traz uma possível variação do exemplo anterior, com a captura apenas das exceções do tipo NameError. 
1 try: 
2 num = eval(input("Entre com um número inteiro: ")) 
3 print(num) 
4 except NameError: 
5 print("Entre com o valor numérico e não letras") 
Captura de exceções de múltiplos tipos 
Python permite que haja diversos tratamentos para diferentes tipos possíveis de exceção. Isso pode 
ser feito com mais de uma cláusula except vinculada à mesma cláusula try. A Figura 48 mostra um exemplo 
de implementação da captura de exceções de múltiplos tipos. 
1 try: 
2 num = eval(input("Entre com um número inteiro: ")) 
3 print(num) 
4 except ValueError: 
5 print("Mensagem 1") 
6 except IndexError: 
7 print("Mensagem 2") 
8 except: 
9 print("Mensagem 3") 
 
A instrução da linha 5 somente será executada se a exceção levantada no bloco try for do tipo 
ValueError, e se, na instrução da linha 7, a exceção for do tipo IndexError. 
Caso a exceção seja de outro tipo, a linha 9 será executada. 
O tratamento completo das exceções 
A forma geral completa para lidar com as exceções em Python é: 
1 try: 
2 Bloco 1 
3 except Exception1: 
4 Bloco tratador para Exception1 
5 except Exception2: 
6 Bloco tratador para Exception1 
7 ... 
8 else: 
9 Bloco 2 – executado caso nenhuma exceção seja levantada 
10 finally: 
11 Bloco 3 – executado independente do que ocorrer 
12 Instrução fora do try/except 
 
As cláusulas else e finally são opcionais, como foi possível perceber nos exemplos iniciais. 
Tratamento de eventos 
O tratamento de eventos é similar ao tratamento de exceções. Assim como podemos tratar as 
exceções ocorridas em tempo de execução, podemos tratar os eventos criados por ações externas, como 
interações de usuário realizadas por meio de uma interface gráfica de usuário (GUI). 
Um evento é a notificação de que alguma coisa aconteceu, como um clique de mouse sobre um 
elemento botão. O tratador do evento é o segmento de código que será executado em resposta à ocorrência 
do evento. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 95 
 
Verificando o aprendizado 
1. Considere o seguinte trecho de um programa escrito em Python: 
1 try: 
2 num = eval(input("Entre com um número inteiro: ")) 
3 print(num) 
4 except ValueError: 
5 print("Mensagem 1") 
6 except IndexError: 
7 print("Mensagem 2") 
8 except: 
9 print("Mensagem 3") 
 
Suponha que durante a execução o usuário entre com a palavra numero quando solicitado. Assinale a opção 
que mostra o resultado imediato dessa ação. 
A. O programa deixará de ser executado. 
B. Será impresso na tela Mensagem 1. 
C. Será impresso na tela Mensagem 2. 
D. Será impresso na tela Mensagem 3. 
 
2. Sobre o tratamento de exceções em Python, é incorreto afirmar que: 
A. É possível implementar tratamentos diferentes de acordo com a exceção levantada. 
B. Não é possível utilizar a cláusula finally. 
C. Não é possível utilizar a cláusula catch. 
D. É possível implementar um tratamento geral para todas as exceções levantadas. 
 
Considerações finais 
Neste tema, você aprendeu a usar as estruturas de controle, sejam de decisão ou de repetição, foi 
apresentado aos conceitos de subprogramas em Python, implementou suas próprias funções, além de 
conhecer e utilizar as bibliotecas. Por fim, analisou as formas de tratamento de exceções e eventos. Com 
esse conteúdo, você com certeza terá condições de desenvolver aplicações muito mais complexas e com 
muito mais recursos. 
Referências 
PERKOVIC, L. Introdução à computação usando Python: um foco no desenvolvimento de aplicações. 
Rio de Janeiro: LTC, 2016. 
SEBESTA, R. W. Conceitos de linguagens de programação. 11. ed. São Paulo: Bookman, 2018. 
Explore+ 
Para ter desafios mais complexos e exercícios para treinar, recomendamos uma visita ao website 
Python Brasil. 
Acesse o site das bibliotecas apresentadas e busque pela documentação para que você possa 
conhecer todas as funcionalidades que estão disponíveis. 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 96 
 
Python Orientado a Objetos 
Definição 
Introdução aos conceitos da orientação a objetos; Classes e Encapsulamento; Herança e 
Polimorfismo; Construtores; Atributos e Métodos; Implementação de Herança; Implementação de 
Polimorfismo; Classes Abstratas; Tratamento de Exceções; Python e linguagens OO. 
Propósito 
Compreender o desenvolvimento de software orientado a objetos, utilizando uma linguagem de 
programação como Python com grande aceitação no meio comercial e acadêmico. Entender os conceitos e 
pilares da orientação a objetos e saber contextualizar o Python entre as outras linguagens tradicionais 
orientadas a objetos como Java e C++. 
Preparação 
Para este módulo, é necessário conhecimentos de programação em linguagem Python, incluindo 
modularização e utilização de bibliotecas em Python. Antes de iniciar o conteúdo deste tema é necessário 
que tenha o interpretador Python na versão 3.7.7 e o ambiente de desenvolvimento PyCharm ou outro 
ambiente que suporte o desenvolvimento na linguagem Python. 
Introdução 
O paradigma de programação orientado a objetos é largamente utilizado para o desenvolvimento de 
software devido à sua implementação ser próxima dos conceitos do mundo real. Essa proximidade facilita a 
manutenção dos softwares orientados a objetos. A linguagem Python implementa os conceitos do paradigma 
orientado a objetos e, devido à sua sintaxe simples e robusta, torna-se uma ferramenta poderosa para a 
implementação de sistemas orientados a objetos. 
Na apostila, serão apresentados os conceitos da orientação a objetos, como implementá-los em 
Python e uma comparação com as linguagens Java e C++ - em relação às principais características da 
orientação a objetos. 
Conceitos gerais da orientação a objetos 
Conceitos de POO - programação orientada a objetos 
A programação orientada a objetos foi considerada uma revolução na programação, pois mudou 
completamente a estruturação dos programas de computador. Essa mudança se estendeu, inclusive, para 
os modelos de análise do mundo real e depois para a implementação dos respectivos modelos nas 
linguagens de programação orientadas a objetos. 
Conforme apresentado por Rumbaugh et al (1994): 
“A tecnologia baseada em objetos é mais do que apenas uma forma de programar. Ela é mais importante como 
um modo de pensar em um problema de forma abstrata, utilizando conceitos do mundo real e não ideias 
computacionais”. Jaeger, 1995. 
Muitas vezes, analisamos um problema do mudo real pensando no projeto, que, por sua vez, é 
influenciado por ideias sobre codificação, que são fortemente influenciadas pelas linguagens de 
programação disponíveis. A abordagem baseada em objetos permite que os mesmos conceitos e a mesma 
notação sejam usados durante todo o processo de desenvolvimento de software, ou seja, não existem 
conceitos de análise de projetos diferentes dos conceitos de implementação dos projetos. A abordagem 
procura refletir os problemas do mundo real através de interação de objetos modelados 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 97 
 
computacionalmente. Portanto, o desenvolvedor do software não necessita realizar traduções para outra 
notação em cada etapa do desenvolvimento de um projeto de software (COSTA, 2015). 
O software é organizado como uma coleção de objetos separados que incorporam, tanto a estrutura, 
quantoo comportamento dos dados. Contrasta com a programação convencional, segundo a qual a 
estrutura e o comportamento dos dados têm pouca vinculação entre si. Os modelos baseados em objetos 
correspondem mais aproximadamente ao mundo real. Em consequência, são mais adaptáveis às 
modificações e evoluções dos sistemas. 
Pilares da orientação a objetos 
Objetos 
Um objeto é a representação computacional de um elemento ou processo do mundo real. Cada 
objeto possui suas características (informações) e uma série de operações (comportamento) que alteram as 
suas características (estado do objeto). Todo o processamento das linguagens de programação orientadas 
a objetos se baseia no armazenamento e na manipulação das informações (estados). São exemplos de 
objetos do mundo real e computacional: Aluno, Professor, Livro, Empréstimo e Locação. (Costa, 2015) 
É importante, durante a etapa de levantamento dos objetos, analisar apenas os objetos relevantes 
(abstrair) com as respectivas características mais importantes para o problema a ser resolvido. Por exemplo, 
as características de uma pessoa para um sistema acadêmico podem ser formação, nome do pai e da mãe, 
enquanto as características de um indivíduo para o sistema de controle de uma academia são altura e peso. 
Atributos 
São propriedades do mundo real que descrevem um objeto. Cada objeto possui suas respectivas 
propriedades do mundo real, os quais possuem valores. A orientação a objetos define as propriedades como 
atributos. O conjunto de valores dos atributos de um objeto definem o seu estado naquele momento 
(RUMBAUGH, 1994). 
Veja nas tabelas a seguir a diferença entre os atributos de duas mulheres: 
 
Fonte: Estácio de Sá 
Operações 
Uma operação é uma função ou transformação que pode ser aplicada a objetos ou dados 
pertencentes a um objeto. Importante dizer que todo objeto possui um conjunto de operações, que podem 
ser chamadas por outros objetos de modo a colaborarem entre si. Esse conjunto de operações é conhecido 
como interface. A única forma de colaboração entre os objetos é por meio das suas respectivas interfaces 
(FARINELLI, 2020). 
Utilizando o exemplo acima, podemos alterar nome, idade e peso da pessoa por meio de um conjunto 
de operações. Portanto, normalmente, essas operações alteram o estado do objeto. Vamos ver a seguir 
outros exemplos de operações: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 98 
 
Exemplo 
Classe empresa = Contratar_Funcionario, Despedir_Fucionario; 
Classe janela = Abrir, fechar, ocultar. 
O desenvolvimento de um sistema orientado a objetos consiste em realizar um mapeamento, 
conforme apresentado na imagem a seguir. 
 
Fonte: Estácio de Sá 
Basicamente, deve-se analisar o mundo real e identificar quais objetos devem fazer parte da solução 
do problema. Para cada objeto identificado, levantam-se os atributos que descrevem as propriedades dos 
objetos e as operações que podem ser executadas sobre esses objetos. 
Classes 
A classe descreve as características e os comportamento de um conjunto de objetos. De acordo com 
a estratégia de classificação, cada objeto pertence a uma única classe e possuirá os atributos e as operações 
definidos na classe. Durante a execução de um programa orientado a objetos, são instanciados os objetos 
a partir da classe, portanto, um objeto é chamado de instância de sua classe. 
A classe é o bloco básico para a construção de programas OO – Orientados a Objetos (COSTA, 
2015). 
Atenção 
Importante ressaltar que cada nome de atributo é único dentro de uma classe, no entanto, essa premissa não 
é verdadeira quando se consideram todas as classes. Por exemplo, as classes Pessoa e Empresa podem ter um 
atributo comum chamado de Endereço. 
Com base na Tabela 1, vista anteriormente, deve ser definida uma classe Pessoa com os atributos 
Nome, Idade, Peso e Altura. A partir da classe Pessoa, pode-se instanciar uma quantidade ilimitada de 
objetos contendo os mesmos atributos. Os objetos de uma classe sempre compartilham o conjunto de 
operações que atuam sobre seus dados, alterando o estado do objeto. 
Um programa orientado a objetos consiste basicamente em um conjunto de objetos que colaboram 
entre si, por meio de uma troca de mensagens, para a solução de um problema computacional. Cada troca 
de mensagens significa a chamada de uma operação feita pelo objeto receptor da mensagem. (COSTA, 
2015) 
Comunicação entre objetos diferentes 
 
Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 99 
 
De acordo com a Figura 2, vista anteriormente, um objeto motorista 1, instanciado a partir da classe 
Motorista, envia a mensagem “Freia” para um objeto carro 1, instanciado a partir da classe Carro. O objeto 
carro 1, ao receber a mensagem, executa uma operação para acionar os freios do automóvel. Essa operação 
também diminuirá o valor do atributo velocidade do objeto carro 1. 
Encapsulamento 
O conceito de encapsulamento consiste na separação dos aspectos externos (operações) de um 
objeto acessíveis a outros objetos, além de seus detalhes internos de implementação, que ficam ocultos dos 
demais objetos (RUMBAUGH, 1994). Algumas vezes, é conhecido como o princípio do ocultamento de 
informação, pois permite que uma classe encapsule atributos e comportamentos, ocultando os detalhes da 
implementação. Partindo desse princípio, a interface de comunicação de um objeto deve ser definida de 
modo a revelar o menos possível sobre o seu funcionamento interno. 
Exemplo 
Foi desenvolvido um objeto ApresentaçãoMapa, pertencente a um aplicativo de entrega móvel, que possui a 
responsabilidade de apresentar um mapa com o menor caminho entre dois pontos. Porém, o objeto não “sabe” como 
calcular a distância entre os dois pontos. 
Para resolver esse problema, ele precisa colaborar com um objeto Mapa que “sabe” calcular e, portanto, possui 
essa responsabilidade. O objeto Mapa implementa essa responsabilidade por meio da operação Calcula Melhor 
Caminho, cujo resultado é a menor rota entre duas coordenadas geográficas. 
Utilizando o encapsulamento, o objeto Mapa calcula e retorna o melhor caminho para o objeto 
ApresentaçãoMapa de maneira transparente, escondendo a complexidade da execução dessa tarefa. 
 
Fonte: Estácio de Sá 
Uma característica importante do encapsulamento é que pode surgir um modo diferente de se 
calcular o melhor caminho entre dois pontos. Por conta disso, o objeto Mapa deverá mudar o seu 
comportamento interno para implementar esse novo cálculo. Porém, essa mudança não afetará o objeto 
ApresentaçãoMapa, pois a implementação foi realizada isoladamente (encapsulamento) no objeto Mapa, 
sem impacto para outros objetos no sistema. 
Resumindo 
Os objetos clientes têm conhecimento apenas das operações que podem ser requisitadas e precisam estar 
cientes apenas do que as operações realizam, e não de como elas estão implementadas. 
Herança 
Na orientação a objetos, a herança é um mecanismo por meio do qual classes compartilham atributos 
e comportamentos, formando uma hierarquia. Uma classe herdeira recebe as características de outra classe 
para reimplementá-las ou especializar de uma maneira diferente da classe pai. A herança permite capturar 
similaridades entre classes, dispondo-as em hierarquias. As similaridades incluem atributos e operações 
sobre as classes (FARINELLI, 2020). 
Essa estrutura reflete um mapeamento entre classes, e não entre objetos, conforme esquema a 
seguir: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 100 
 
 
Fonte: Estácio de Sá 
No esquema anterior, as classes Carro, Moto, Caminhão e Ônibus herdam características em comum 
da classe Veículo, como os atributos chassis, ano, cor e modelo. 
Uma classe pode ser definida genericamente como uma superclasse e, depois, especializada em 
classes mais específicas (subclasses). A herança permitea reutilização de código em larga escala, pois 
possibilita que se herde todo o código já implementado na classe pai e se adicione apenas o código 
específico para as funcionalidades novas implementadas pela classe filha. 
A evolução dos sistemas orientados a objetos também é facilitada, pois, caso surja uma classe nova 
com atributos e/ou operações comuns a outra, basta inseri-la na hierarquia, acelerando a implementação. 
Veja a seguir os tipos de herança: 
Herança simples 
A herança é considerada simples quando uma classe herda as características existentes apenas de 
uma superclasse. 
Na figura a seguir, temos uma superclasse Pessoa que possui os atributos CPF, RG, Nome e 
Endereço. Em seguida, a classe Professor precisa herdar os atributos da superclasse Pessoa, além de 
adicionar atributos específicos do contexto da classe Professor, como titularidade e salário. 
 
Figura 5 – Exemplo de herança Pessoa -> Professor. 
Considerando um sistema acadêmico, a classe Aluno também se encaixaria na hierarquia acima, 
tornando-se uma subclasse de Pessoa. Porém, precisaria de outros atributos associados a seu contexto, 
como curso e Anoprevformatura. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 101 
 
 
Figura 6 – Exemplo de herança Pessoa -> Professor e Pessoa -> Aluno. 
Herança múltipla 
A herança é considerada múltipla quando uma classe herda características de duas ou mais 
superclasses. Por exemplo, no caso do sistema acadêmico, o docente também pode desejar realizar um 
outro curso de graduação na mesma instituição em que trabalha. Portanto, ele possuirá os atributos da 
classe Professor e os da classe Aluno. Além disso, haverá também um atributo DescontoProfessor, o qual 
apenas quando houver a associação professor e aluno com a universidade. 
Para adaptar essa situação no mundo real, deve ser criada uma modelagem de classes. Uma nova 
subclasse ProfessorAluno precisa ser adicionada, herdando atributos e operações das classes Professor e 
Aluno. Isso configura uma herança múltipla. Essa nova subclasse deverá ter o atributo DescontoProfessor, 
que faz sentido apenas para essa classe. 
 
Figura 7 – Exemplo de herança Pessoa -> Professor e Pessoa -> Aluno e Professor/Aluno ->ProfessorAluno. 
Polimorfismo 
O Polimorfismo é a capacidade de um mesmo comportamento diferente em classes diferentes. Uma 
mesma mensagem será executada de maneira diversa, dependendo do objeto receptor. O polimorfismo 
acontece quando reimplementamos um método nas subclasses de uma herança (FARINELLI, 2020). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 102 
 
 
Fonte: Estácio de Sá 
Como exemplificado na figura 1.8, o comportamento mover() em um objeto instanciado pela classe 
Aereo será diferente do mover() em um objeto da classe Terrestre. Um objeto poderá enviar uma mensagem 
para se mover e o objeto receptor decidirá como isso será feito. 
Verificando o aprendizado 
1. Na programação orientada a objetos, temos conceitos como Herança e Polimorfismo. Sobre esses conceitos 
analise as assertivas e assinale a alternativa que aponta a(s) correta(s). 
I. Para evitar código redundante, o paradigma de orientação a objetos oferece uma estrutura 
hierárquica e modular para reutilização de código através de uma técnica conhecida como 
herança. 
II. Herança permite projetar classes genéricas que podem ser especializadas em classes mais 
particulares, onde as classes especializadas reutilizam o código das mais genéricas. 
III. Literalmente, “polimorfismo” significa “muitas formas”. No contexto e projeto orientado a 
objetos, entretanto, refere-se à habilidade de uma variável de objeto de assumir formas 
diferentes. 
IV. Polimorfismo permite que os atributos de uma classe não tenham acesso diretamente. 
A. Apenas I. 
B. Apenas I e III. 
C. Apenas I, II e III. 
D. Apenas II, III e IV. 
 
2. Os bancos são instituições que investem fortemente na área de Tecnologia da Informação, inclusive com a 
contratação de milhares de profissionais e a construção de grandes ambientes de datacenter. Por isso, é um domínio 
de conhecimento bastante importante e que deve ser utilizado como exemplo durante um curso de graduação. Sabendo 
disso, analise a seguinte situação em um sistema bancário: A ContaBancaria(CB) especializa as classes 
ItemSuportado (IS) e ItemSujeitoAJuros (ISJ) e generaliza as classes ContaCorrente (CC) e Poupança (PP). Nesse 
sentido, é correto afirmar que ocorre (0,5) 
A. Relação de dependência entre IS e ISJ. 
B. Relação de dependência entre CC e PP. 
C. Herança múltipla de CB em relação a CC e PP. 
D. Herança múltipla de CB em relação a IS e ISJ. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 103 
 
Conceitos básicos da programação orientada a objetos na 
linguagem Python 
Classes e objetos em Python 
Uma classe é uma declaração de tipo que encapsula constantes, variáveis e métodos que realizam 
manipulação dos valores dessas variáveis. Cada classe deve ser única em um sistema orientado a objetos. 
Definição de classe 
Como boa prática, cada classe deve fazer parte de um único arquivo.py para ajudar na estruturação 
do sistema orientado a objetos em Python. Outra boa prática consiste no nome da classe semelhante ao do 
arquivo. Por exemplo, definir no ambiente de desenvolvimento Python a classe Conta. O nome final do 
arquivo deve ser Conta.py. 
Deve-se ressaltar que todos esses exemplos podem ser executados no terminal do Python. 
Arquivo Conta.py 
class Conta: 
pass 
 
Uma classe é definida utilizando a instrução class e: para indicar o início do bloco de declaração da 
classe. A palavra reservada pass indica que a classe será definida posteriormente, servindo apenas para 
permitir que o interpretador execute a classe até o final sem erros. 
Recomendação 
É recomendável que você reproduza e execute todos os exemplos que serão apresentados a seguir. 
Construtores e self 
A classe conta foi criada, porém não lhe foram definidos atributos e instanciados objetos, 
característica básica dos programas orientados a objetos. Nas linguagens orientadas a objetos, para se 
instanciar objetos, devemos criar os construtores da classe. 
Em Python, a palavra reservada __init__() serve para inicialização de classes, como abaixo: 
class Conta: 
def__init__(self, numero, cpf, nomeTitular, saldo): 
self.numero = numero 
self.cpf = cpf 
self.nomeTitular = nomeTitular 
self.saldo = saldo 
Figura 9 - Classe Conta Inicial. 
Diferentemente de outras linguagens de programação orientadas a objetos, o Pyhton constrói os 
objetos em duas etapas. A primeira etapa é utilizada com a palavra reservada __new__, que, em seguida, 
executa o método __init__. 
O __new__ cria a instância e é utilizado para alterar as classes dinamicamente para casos de 
sistemas que envolvam metaclasses e frameworks. Após __new__ ser executado, este método chama o 
__init__ para inicialização da classe como seus valores iniciais (MENEZES, 2019). 
Para efeitos de comparação com outras linguagens de programação, e por questões de simplificação, 
consideraremos o __init__ como o construtor da classe. Portanto, toda vez que instanciarmos objetos da 
classe conta, será chamado o método __init__. 
Analisando o nosso exemplo anterior, vimos a utilização da palavra self como parâmetro no 
construtor. Como o objeto já foi instanciado implicitamente pelo __new__, o método __init__ recebe uma 
referência do objeto instanciado como self. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 104 
 
Analisando o restante do construtor da Figura 9, o código possui diversos comandos self, o qual 
indica referência ao próprio objeto. Por exemplo, o comando self.numero indica que o número é um atributo 
do objeto, ao qual é atribuído um valor. O restante dos comandos self indicam que foram criados os atributos 
cpf, nomeTitular e saldo referentesa classe Conta. 
Vamos instanciar o nosso objeto com o método __init__: 
>>>from Conta import Conta 
>>>c1 = Conta(1,1,"Joao",1000) 
Importante ressaltar que, em Python, não é obrigatório ter um método construtor na classe, apenas 
se for necessária alguma ação na construção do objeto, como inicialização e/ou atribuição de valores. Segue 
um exemplo de uma classe sem um método construtor: 
class A(): 
def f(): 
print ‘foo’ 
Figura 10 – Exemplo de classe sem construtor. 
Métodos 
Toda classe deve possuir um conjunto de métodos para manipular os atributos e, por consequência, 
o estado do objeto. Por exemplo, precisamos depositar dinheiro na conta para aumentar o valor da conta 
corrente: 
def __depositar__(self,valor) 
 self.saldo += valor 
No código acima, foi definido um método __depositar__ que recebe a própria instância do objeto 
através do self e de um parâmetro valor. O número passado por meio do parâmetro será adicionado ao 
saldo da conta do cliente. Vamos supor que o estado anterior do objeto representasse o saldo com o valor 
zero da conta. Após a chamada desse método passando como parâmetro o valor 300, através da referência 
self, o estado da conta foi alterado com o novo saldo de 300 reais. 
Segue o novo código: 
class Conta: 
def__init__(self, numero, cpf, nomeTitular, saldo): 
self.numero = numero 
self.cpf = cpf 
self.nomeTitular = nomeTitular 
self.saldo = saldo 
def depositar(self, valor): 
self.saldo += valor 
def sacar(self, valor): 
self.saldo -= valor 
Figura 11 – Classe com métodos depositar e sacar. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 105 
 
No exemplo anterior, adicionamos mais um método sacar(self, valor), onde subtraímos o valor, 
passado como parâmetro, do saldo do cliente. Pode ser adicionado um método extrato para avaliar os 
valores atuais da conta corrente, ou seja, o estado atual do objeto. Por exemplo, a conta tinha saldo de 300 
reais após o primeiro depósito. Após a chamada de sacar (100), o saldo da conta será 200 reais. 
>>>from Conta import Conta 
>>>c1 = Conta(1,1,"Joao",0) 
.....c1.depositar(300) 
.....c1.sacar(100) 
 
class Conta: 
def__init__(self, numero, cpf, nomeTitular, saldo): 
self.numero = numero 
self.cpf = cpf 
self.nomeTitular = nomeTitular 
self.saldo = saldo 
def depositar(self, valor): 
self.saldo += valor 
def sacar(self, valor): 
self.saldo -= valor 
def gerarextrato(self): 
print(f"numero: {self.numero} \n cpf: {self.cpf}\nsaldo: {self.saldo") 
Figura 12 – Classe com métodos depositar/sacar/gerarextrato. 
Se o método gerarextrato() for executado, o valor impresso será: 
....c1.geratextrato() 
200 
Métodos com retorno 
Em Python, não é obrigatório um comando para indicar quando o método deve ser finalizado. Porém, 
na orientação a objetos, como na programação procedural, é bastante comum retornar um valor a partir da 
análise do estado do objeto. Conforme exemplificado a seguir, não é permitido o saque de um valor maior 
do que o saldo atual do cliente, portanto, retorna a resposta “False” para o objeto que está executando o 
saque. O método deve ficar da seguinte forma: 
def sacar(self,valor): 
if self.saldo < valor: 
return False 
else: 
self.saldo -= valor 
return True 
Figura 13 – Método sacar com retorno. 
....c1.sacar(100) 
True 
 
Agora, questione-se: ao executar o comando c1.sacar(300), qual será o retorno? 
Referências entre objetos na memória 
Uma classe pode ter mais de uma ou várias instâncias de objetos na memória, como exemplificado 
na imagem a seguir: 
from Conta import Conta 
conta1 = Conta(1, 123, ‘Joao’,0) 
conta2 = Conta(3, 456, ‘Maria’,0) 
Figura 14 – Método sacar com retorno. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 106 
 
O Resultado na memória após a execução é apresentado na Figura 15: 
 
Figura 15 – Estado da memória conta1 e conta2. Fonte: Estácio de Sá 
 
Na memória, foram criados dois objetos diferentes referenciados pelas variáveis conta1 e conta2 do 
tipo conta. Os operadores “==” e “!=” comparam se as duas variáveis de referência apontam para o mesmo 
endereço de memória (CAELUM, 2020). 
>>>if (conta1 != conta2): 
... print("Endereços diferentes de memória") 
Pelo esquema da memória, apresentado na Figura 15, realmente conta1 e conta2 apontam para 
endereços diferentes de memória. 
O comando “=” realiza o trabalho de igualar a posição de duas referências na memória. 
Fazendo conta1 = conta2, podemos ver o resultado: 
conta1 = conta2 
if (conta1 == conta2): 
... print("enderecos iguais de memoria") 
 
Figura 16 – Estado da memória conta1 e conta2 no mesmo endereço. Fonte: Estácio de Sá 
Se executarmos os comandos referenciando o CPF da conta, verificamos que possuem os mesmos 
valores, conforme mostrado acima. 
>>>conta1.cpf 
456 
>>> conta2.cpf 
456 
Esse exemplo pode ser estendido para realizar uma transferência de valores de uma conta para 
outra. A segunda conta deve ser passada como parâmetro do método para ser executada a transferência. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 107 
 
O método deve ficar da seguinte maneira: 
class Conta: 
def__init__(self, numero, cpf, nomeTitular, saldo): 
self.numero = numero 
self.cpf = cpf 
self.nomeTitular = nomeTitular 
self.saldo = saldo 
def depositar(self, valor): 
self.saldo += valor 
def sacar(self,valor): 
if self.saldo < valor: 
return False 
else 
self.saldo -= valor 
return True 
def gerarextratp(self): 
print(f"numero:{self.numero}\n cpf:{self.cpf}\nsaldo:{selfsaldo}") 
def transfereValor(self,contaDestino,valor): 
if self.saldo < valor: 
return ("Não existe saldo suficiente") 
else: 
contaDestino.depositar(valor) 
self.saldo -= valor 
return("Transferencia Realizada") 
Figura 17 – Classe conta com transferência. 
>>>from Conta import Conta 
... conta1 = Conta(1, 123,'Joao',0) 
... conta2 = Conta(3, 456,'Maria',0) 
... conta1.depositar(1000) 
... conta1.transfereValor(conta2,500) 
... print(conta1.saldo) 
... print(conta2.saldo) 
500 
500 
Em resumo, foi depositado 1000 na conta1 e realizada uma transferência de valor de 500 para 
conta2. No final, o saldo ficou 500 para conta1 e 500 para conta2. 
Importante ressaltar que, no comando conta1.transfereValor(conta2,500), é passada uma referência 
da conta2 para o objeto contaDestino por meio de um operador “=”. O comando contaDestino = conta2 é 
executado internamente no Python. 
Agregação 
Para atender novas necessidades do sistema de conta corrente do banco, agora se faz necessário 
adicionar uma funcionalidade para gerenciamento de conta conjunta, ou seja, uma conta corrente pode ter 
um conjunto de clientes associados. Isto pode ser representado como uma agregação, conforme 
apresentado no esquema a seguir. Uma observação: o losango na imagem tem a semântica da agregação. 
 
Fonte: Estácio de Sá 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 108 
 
Para agregação, devemos criar dois arquivos contas.py e cliente.py: 
class Clientes: 
def__init__(self,cpf,nome,endereco): 
self.cpf = cpf 
self.nome = nome 
self.endereco = endereço 
Figura 19 – Classe clientes.py. 
 
class Conta: 
def__init__(self, clientes, numero, saldo): 
self.clientes = clientes 
self.numero = numero 
self.saldo = saldo 
def depositar(self, valor): 
self.saldo += valor 
def sacar(self,valor): 
if self.saldo < valor: 
return False 
else: 
self.saldo -= valor 
return True 
def transfereValor(self,contaDestino,valor): 
if self.saldo < valor: 
return ("Não existe saldo suficiente") 
else: 
contadestino.depositar(valor) 
self.saldo -= valor 
return("Transferencia Realizada") 
def gerarsaldo(self): 
print(f"numero:{self.numero\n saldo: {self.saldo}") 
 Figura 20 – Classe contas.py 
Um programa testecontas.py deve ser criado para o usarmos na instanciação dos objetosdas duas 
classes e gerarmos as transações realizadas nas contas dos clientes. 
from contas import Conta 
from clientes import Cliente 
cliente1 = Cliente(123, “Joao”, “Rua 1”) 
cliente2 = Cliente(345, “Maria”,”Rua 2”) 
conta1 = Conta([cliente1,cliente2], 1,0) (1) 
conta1.gerarsaldo() 
conta1.depositar(1500) 
conta1.sacar(500) 
conta1.gerarsaldo() 
Figura 21 – Classe contasclientes.py. 
Atenção 
Em (1) foi instanciado um objeto conta1 com dois clientes agregados: cliente1 e cliente2. Esses dois objetos 
são passados como parâmetros em (1). 
Qual o resultado dessa execução? Qual valor final na conta? 
Sugestão: altere o programa do código anterior para criar mais uma conta para dois clientes diferentes. Como 
desafio, tente, através do objeto conta, imprimir o nome e o endereço dos clientes associados às contas. 
Composição 
A classe conta ainda não está completa de acordo com as necessidades do sistema de conta 
corrente do banco. Isso ocorre porque o banco precisa gerar extratos contendo o histórico de todas as 
operações realizadas para conta corrente. Para isso, o sistema deve ser atualizado para adicionar uma 
composição de cada conta com o histórico de operações realizadas. O diagrama a seguir representa a 
composição entre as classes Conta e Extrato. Esta composição representa que uma conta pode ser 
composta por vários extratos. Uma observação: o losango preenchido tem a semântica da composição. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 109 
 
 
Figura 22 – Classe Conta composta de 1 ou mais extratos. Fonte: Estácio de Sá 
A classe Extrato tem as responsabilidades de armazenar todas as transações realizadas na conta e 
de conseguir imprimir um extrato com a lista dessas transações. 
class Extrato: 
def__init_(self): 
self.transacoes = [] 
 
def extrato(self, numeroconta): 
print(f”Extrato : {numeroconta} \n”) 
for p in self.transacoes: 
print(f”{p[0]:15s} {p[1]:10.2f} {p[2]:10s} {p[3].strftime(‘%d/%b/%y)}”) 
Figura 23 – Classe extrato.py. 
A classe conta possui todas as transações como sacar, depositar e transferir_valor. Cada transação 
realizada deve adicionar uma linha ao extrato da conta. Inclusive, a composição Conta->Extrato deve ser 
inicializada no construtor da classe Conta, conforme exemplificado na Figura 23. No construtor de Extrato, 
foi adicionado um atributo transações, o qual foi inicializado para receber um array de valores – transações 
da conta. 
A classe Conta alterada deve ficar da seguinte maneira: 
import datetime 
from Extrato import Extrato 
class Conta: 
def__init__(self,clientes,numero,saldo): 
self.clientes = clientes 
self.numero = numero 
self.saldo = saldo 
self.sata abertura = datetime.satetime.today() 
self.extrato = Extrato () (1) 
def depositar(self, valor): 
self.saldo += valor 
self.extrato.trasacoes.append(["DEPOSITO", valor, "Data",datetime.datetime.today ()])(2) 
def sacar(self, valor): 
if self.saldo < valor: 
return False 
else: 
self.saldo -= valor 
self.extrato.transacoes.append(["SAQUE", valor, "Data", datetime.datetime.today()]) (3) 
return True 
def transfereValor(self, contadestino, valor): 
if self.saldo < valor: 
return "Não existe saldo suficiente" 
else: 
contadestino.depositar(valor) 
self.saldo -= valor 
self.extrato.transacoes.append(["TRANSFERENCIA", valor, "Data", datetime.datetime.today()]) (4) 
return "Transferencia Realizada" 
def gerarsaldo(self): 
print(f"numero: {self.unmero}\n saldo:{self.saldo}") 
Figura 24 – Classe conta.py composta. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 110 
 
Alterações da classe conta: 
Adição da linha (1) – criação de um atributo extrato, fazendo referência a um objeto Extrato 
Adição das linhas (2), (3) e (4) – adição de linhas ao array de transações do objeto Extrato através 
do atributo extrato. 
Execução no terminal: 
>>>from clientes import Cliente 
... from ContasClientesExtrato import Conta 
... cliente1 = Cliente("123","Joao","Rua X") 
... cliente2 = Cliente ("456","Maria","Rua W") 
... conta1 = Conta([cliente1,cliente2],1,2000) 
... conta1.depositar(1000) 
... conta1.sacar(1500) 
conta1.extrato.extrato(conta1.numero) 
Extrato : 1 
DEPOSITO 1000.00 Data 14/Jun/2020 
SAQUE 1500.00 Data 14/Jun/2020 
Dica 
Experimente adicionar mais uma conta e realize uma transferência de valores entre ambas. Depois, crie uma 
classe Banco para armazenar todos os clientes e todas as contas do banco. 
Encapsulamento 
Conforme apresentado no módulo anterior, o encapsulamento é fundamental para a manutenção da 
integridade dos objetos e proibir qualquer alteração indevida nos valores dos atributos (estado) do objeto 
(CAELUM, 2020). Este ponto foi fundamental para a popularização da orientação aos objetos: reunir dados 
e funções em uma única entidade e proibir a alteração indevida dos atributos. 
Exemplo 
No caso da classe conta, imagine que algum programa tente realizar a seguinte alteração direta no valor do 
saldo: 
conta1.saldo = -200 
Esse comando viola a regra de negócio do método sacar(), que indica para não haver saque maior 
do que o valor e deixar a conta no negativo (estado inválido para o sistema). 
def sacar(self, valor): 
if self.saldo < valor: 
return False 
 
else: 
self.saldo -= valor 
self.extrato.transacoes.append(["SAQUE", valor, "Data", datetime.datetime.today()]) 
return True 
Figura 25 – Método sacar no estado inválido. 
Como proibir alterações indevidas dos atributos em Python? 
Atributos públicos e privados 
Para seguir o encapsulamento e proibir alterações indevidas dos atributos, devemos definir atributos 
privados para a classe. Por default, em Python, os atributos são definidos como público, ou seja, podem ser 
acessados diretamente sem respeitar o encapsulamento - acesso feito apenas através de métodos do 
objeto. 
Para tornar um atributo privado, devemos iniciá-lo com dois underscores (‘__’). A classe conta possui 
todos os atributos privados: 
>>>class Conta: 
... def__init__(self,numero,saldo): 
... self.numero = __numero 
... self.saldo = __saldo: 
Figura 26 – Classe Conta com atributos privados. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 111 
 
Qual o retorno do interpretador ao se acessar um atributo privado para classe Conta? 
>>> conta = Conta(1,1000) 
>>> conta.saldo 
Traceback (most recent call last): 
File "<input>", line 1, in <module> 
AttributeError: 'Conta' object has no attribute 'saldo' 
É importante ressaltar que, em Python, não existe realmente atributos privados. O interpretador 
renomeia o atributo privado para _nomedaClasse__nomedoatributo. Portanto, o atributo ainda pode ser 
acessado. Embora funcione, é considerado uma prática que viola o princípio de encapsulamento da 
orientação a objetos. 
>>> conta._Conta__saldo 
1000 
Na prática, deve existir uma disciplina para não serem acessados diretamente os atributos como __ 
ou _ definido nas classes. 
Decorator @property 
Uma estratégia importante disponibilizada pelo Python são as properties. Utilizando o decorator 
property nos métodos, mantém-se os atributos como protegidos, e estes são acessados apenas através dos 
métodos “decorados” com property (CAELUM, 2020). 
No caso da classe conta, não se pode acessar o atributo saldo (privado) para leitura. Com o código, 
ele será acessado pelo método decorator @property: 
@property 
def saldo(self): 
 return self._saldo 
Figura 27 – Definição de uma propriedade. 
Os métodos decorados com a property @setter forçam que todas alterações de valor dos atributos 
privados devem passar por esses métodos. 
Notação: 
@<nomedometodo>.setter 
@saldo.setter 
def saldo(self, saldo): 
if (self.saldo < 0): 
print(“saldo inválido”) 
else: 
self._saldo = saldo 
Figura 28 – Definição de um método setter. 
Os properties ajudam a garantir o encapsulamento no Python. Uma boa prática implementada emtodas as linguagens orientadas a objetos é definir esses métodos apenas se realmente houver regra de 
negócios diretamente associada ao atributo. Caso não haja, deve-se deixar o acesso aos atributos conforme 
definido na classe. 
Atributos de classe 
Existem algumas situações que os sistemas precisam controlar valores associados à classe, e não 
aos objetos (instâncias) das classes; por exemplo, ao desenvolver um aplicativo de desenho, como o Paint, 
que precisa contar o número de círculos criados na tela. 
Inicialmente, a classe Circulo vai ser criada: 
class Circulo(): 
def__init__(self,pontox,pontoy,raio): 
self.pontox = pontox 
self.pontoy = pontoy 
self.raio = raio 
Figura 29 – Classe Circulo. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 112 
 
No entanto, conforme mencionado, é necessário controlar a quantidade de círculos criados. 
class Circulo(): 
total_circulos = 0 (1) 
def__init__(self,pontox, pontoy, raio): 
self.pontox = pontox 
self.pontoy = pontoy 
self.raio = raio 
self.total_circulos +=1 (2) 
Figura 30 – Classe Circulo com atributo de classe. 
Em (1), indicamos para o interpretador que seja criada uma variável total_circulos. Como a 
declaração está localizada antes do init, o interpretador “entende” que se trata de uma variável de classe, 
ou seja, terá um valor único para todos objetos da classe. Em (2), é atualizado o valor da variável de classe 
a cada instanciação de um objeto da classe Circulo. 
Como acessar os valores armazenados em uma variável de classes? 
>> from Circulo import Circulo 
>>>circ1 = Circulo(1,1,10) 
>>>circ1.total_circulos 
>>>circ2 = Circulo(2,2,20) 
>>>circ2.total_circulos 
>>>Circulo.total_circulos 
Esse acesso direto ao valor da variável de classe não é desejado. Deve-se colocar a variável com 
atributo privado com o underscore ‘_’. Como fica agora? O resultado é apresentado a seguir. 
class Circulo: 
_total_circulos = 0 
def__init__(self,pontox, pontoy, raio): 
self.pontox = pontox 
self.pontoy = pontoy 
self.raio = raio 
circulo._total_circulos += 1 
Figura 31 – Classe Circulo com atributo de classe privado 
Repetindo o mesmo código: 
>>>from Circulo import Circulo 
>>>circ1 = Circulo(1,1,10) 
>>>circ1._total_circulos 
1 
>>>Circulo.total_circulos 
Traceback (most recent call last): 
File "<input>", line 1, in <module> 
AttributeError: type object 'Circulo' has no attribute 'total_circulos' 
Métodos de classe 
Os métodos de classe são a maneira indicada para se acessar os atributos de classe. Eles têm 
acesso diretamente à área de memória que contém os atributos de classe. O esquema é apresentado na 
imagem a seguir. 
 
Figura 32 – Memória Estática. Fonte: Estácio de Sá 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 113 
 
Para definir um método como estático, deve-se usar o decorator @classmethod. Assim, segue a 
classe Circulo alterada: 
class Circulo: 
 
_total_circulos = 0 
 
def__init__(self, pontox, pontoy, raio): 
self.pontox = pontox 
self.pontoy = pontoy 
self.raio = raio 
type(self)._total_circulos +=1 
 
@classmethod 
def get total_circulos(cls): (1) 
return cls.total_circulos (2) 
Figura 33 – Método de classe. 
Em (1), é criado o parâmetro cls como referência para classe. Em (2), é retornado o valor do atributo 
de classe _total_circulos. 
Métodos públicos e privados 
As mesmas regras definidas para atributos são válidas para os métodos das classes. Assim, o 
método pode ser declarado como privado, mas ainda pode ser chamado diretamente, como se fosse um 
método público. Os dois underscores antes do método indicam que ele é privado: 
class Circulo: 
def__init__(self,clientes,numero,saldo): 
self.clientes = clientes 
self.numero = numero 
self.saldo = saldo 
 
def __gerarsaldo(self): 
print(f"numero: {self.numero}\n saldo:{self.saldo}") 
Figura 34 – Método privado. 
No código acima, foi definido o método geralsaldo como privado. Portanto, pode ser acessado 
apenas internamente pela classe Conta. Um dos principais padrões da orientação a objetos consiste nos 
métodos públicos e nos atributos privados. Desse modo, respeita-se o encapsulamento. 
Métodos estáticos 
São métodos que podem ser chamados sem ter uma referência para um objeto da classe, ou seja, 
não existe obrigatoriedade da instanciação de um objeto da classe. O método pode ser chamado 
diretamente: 
import math 
class Math: 
@staticmethod 
def sqrt(x): 
return math.sqrt(x) 
Figura 35 – Método estático. 
>>> Math.sqrt(20) 
4.47213595499958 
No caso acima, foi chamado o método sqrt da classe Math sem haver instanciado um objet da classe 
Math. Os métodos estáticos não são uma boa prática na programação orientada a objetos. Devem ser 
utilizados apenas em casos especiais, como classes de log em sistemas. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 114 
 
Verificando o aprendizado 
1. Analise o seguinte código escrito em Python, que define a estrutura da classe ContaBancaria: 
class ContaBancaria: 
num_contas = 0 
def__init__(self,clientes,numero,saldo): 
self.agencia = agencia 
self.numero = numero 
self.saldo = saldo 
ContaBancaria.num_contas += 1 
def _del_(self): 
ContaBancaria.num_contas -= 1 
def depositar(self,valor): 
self.saldo = self.valor + valor 
def sacar(self, valor): 
self.saldo = self.valor - valor 
def consultarSaldo(Self): 
return self.saldo 
Sobre a classe acima e as regras de programação orientada a objetos em Python, a opção INCORRETA: 
A. A criação de objetos chama primeiro o método __new__() e, em seguida, o __init__(). 
B. A palavra self deve ser fornecida como argumento em todos os métodos públicos de instâncias. 
C. A variável num_contas é encapsulada e individual para cada instância da classe. 
D. O método __del__ é privado. 
A instância do objeto (self) deve ser passada implicitamente em cada chamada do método. 
 
2. Qual a diferença na utilização dos decorators @staticmethod e @classmethod: 
A. O decorator @staticmethod definem métodos de classe que manipulam atributos de classe. 
B. O decorator @classmethod definem métodos estáticos que permite acesso a métodos sem 
instanciação da classe. 
C. O decorator @classmethod permite que que os atributos de classe sejam alterados na área de 
memória. 
D. Os decorators @staticmethod e @classmethod podem ser usados de forma intercambiáveis. 
O decorator @classmethod fica armazenado na mesma área de memória dos atributos de classe. Portanto, 
pode alterar os valores dos atributos de classe. 
Conceitos da orientação a objetos como Herança e Polimorfismo 
Herança e polimorfismo 
As linguagens orientadas a objeto oferecem recursos que permitem o desenvolvimento de sistemas 
de uma forma mais ágil e eficiente. Esses recursos são a herança, polimorfismo e o tratamento das 
exceções. A herança permite uma redução da repetição de código, permitindo que uma classe filho herde 
métodos e atributos da classe pai. O polimorfismo permite que, em determinadas situações, os objetos 
possam ter comportamentos específicos. Caso haja algum problema durante a execução do código, o 
tratamento de exceções facilita a manipulação do erro. 
Herança 
É um dos princípios mais importantes da programação orientada a objetos, pois permite a reutilização 
de código com a possiblidade de extensão para se ajustar às regras de negócio dos sistemas. 
Exemplo 
A área de produtos do banco define quais clientes podem ter acesso a um produto chamado Conta especial, o 
qual busca atender quem possui conta na instituição há mais de um ano. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 115 
 
Na visão de negócios, a conta especial possui a funcionalidade de permitir o saque da conta corrente 
até um certo limite, determinado durante a criação da conta. Nesse ponto, há um dos grandes ganhos da 
orientação a objetos. O objeto do mundo real ContaEspecial será mapeado para uma classe ContaEspecial 
que herdará todo código de Conta, conforme a figura 36: 
 
Figura 36 - Herança Conta -> ContaEspecial. Fonte: Estácio de Sá 
Este é o código da implementação da nova classe Conta Especial: 
from ContasClientesExtrato import Conta 
import datetime 
 
class ContaEspecial(Conta): 
def__init__(self,clientes,numero,saldo,limite): 
Conta.__init__(self,clientes,numero,saldo) (1) 
self.limite = limite (2) 
def sacar(self, valor): (3) 
if (self.saldo + self.limite) < valor: 
return False 
else: 
self.saldo -= valor 
self.extrato.transacoes.append(["SAQUE", valor "Data", datetime.datetime.today()]) 
return True 
Figura 37 - Classe ContaEspecial. 
Analisando o código ContaEspecial acima, tem-se as seguintes modificações: 
Método construtor __init__ 
A classe tem que ser instanciada com passagem do limite como um parâmetro da construção do 
objeto. O método __Init__ foi sobrescrito da superclasse Conta. O método super() foi utilizado para 
chamar um método da superclasse e pode ser utilizado em qualquer método da subclasse (REAL 
PYTHONON, 2020). A orientação a objetos permite, inclusive, a reutilização do construtor da classe 
pai (1). 
Atributo limite 
Foi adicionado apenas na subclasse ContaEspecial, onde será utilizado para implementar a regra 
de saques além do valor do saldo (2). 
Método sacar() 
O método precisa verificar se o valor a ser sacado, passado como parâmetro, é menor do que a 
soma do saldo atual mais o limite da conta especial. Nesse caso, a classe Conta Especial 
reescreveu o método sacar da superclasse Conta. Essa característica é conhecida como 
sobrescrita (override) dos métodos (3). 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 116 
 
A execução no terminal gera o seguinte: 
 
>>>from clientes import Cliente 
... from ContasClientesExtrato import Conta 
... from ContaEspecial import ContaEspecial 
... cliente1 = Cliente("123","Joao","Rua X") 
... cliente2 = Cliente ("456","Maria","Rua W") 
... cliente3 = Cliente ("789","Joana", "Rua H") 
... conta1 = Conta([cliente1,cliente2],1,2000) 
... conta2 = ContaEspecial([cliente3],3,1000,2000) 
... conta2.depositar(100) 
... conta2.sacar(3200) 
Valor do Saque 3200.00 maior que o valor do saldo mais o limite 3100.00 
>>> conta2.extrato.extrato(conta2.numero) 
Extrato : 3 
DEPOSITO 100.00 Data 14/Jun/2020 
 
Veja o diagrama atualizado com a implementação dos métodos na subclasse: 
 
Figura 38. Herança Conta -> ContaEspecial. Fonte: Estácio de Sá 
Importante ressaltar que ContaEspecial é uma classe comum e pode ser instanciada como todas as 
outras classes independentes da instanciação de objetos da classe Conta. 
Uma análise comparativa com a programação procedural indica que, mesmo em caso com código 
parecido, o reuso era bastante baixo. O programador tinha que criar um programa Conta Corrente Especial 
repetindo todo o código já definido no programa Conta Corrente. Com a duplicação do código, era necessário 
realizar manutenção de dois códigos parecidos em dois programas diferentes. 
Herança Múltipla 
A herança múltipla é um mecanismo que possibilita uma classe herdar código de duas ou mais 
superclasses. Esse mecanismo é implementado por poucas linguagens orientadas a objetos e insere uma 
complexidade adicional na arquitetura das linguagens. 
Para nosso sistema, vamos considerar a necessidade de um novo produto que consiste em uma 
conta corrente, similar a definida anteriormente no sistema, com as seguintes características: 
Deverá ter um rendimento diário com base no rendimento da conta poupança. 
Deverá ser cobrada uma taxa de manutenção mensal, mesmo se o rendimento for de apenas um 
dia. 
A Classe Poupança também será criada para armazenar a taxa de renumeração e o cálculo do 
rendimento mensal da poupança. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 117 
 
Este será o diagrama com as novas classes criadas no sistema de conta corrente: 
 
Figura 39. Herança Múltipla. Fonte: Estácio de Sá 
A implementação ficou detalhada nos códigos a seguir: 
import datetime 
class ContaPoupanca: 
def__init__(self,taxaremuneracao): 
self.taxaremuneracao = taxaremuneracao 
self.data_abertura = datetime.datetime.today() 
 
def remuneracaoConta(self) 
self.saldo +=self.saldo * self.taxaremuneracao 
Figura 40 - Conta Poupança. 
from ContasClientesExtrato import Conta 
from ContaPoupanca import Poupanca 
 
class ContaRemuneradaPoupanca(Conta, Poupanca): (1) 
def__init__(self, taxaremuneracao, clientes, numero, saldo, taxaremuneracao): 
Conta.__init__(self,clientes,numero,saldo) (2) 
Poupanca.__init__(self,taxaremuneracao) (2) 
self.taxaremuneracao = taxaremuneracao 
 
def remuneraConta(Self): 
self.saldo += self.saldo * (self.taxaremuneracao/30) 
self.saldo -= self.taxaremuneracao 
Figura 41 - Conta Remunerada. 
Alguns pontos importantes sobre a implementação: 
Declaração de herança múltipla: em (1) indica que a classe é herdeira de Conta e Poupança nessa 
ordem. Essa ordem tem importância, pois existem dois métodos no pai com o mesmo nome. O 
Python dá prioridade para a primeira classe que implementa esse método na ordem da declaração 
– (PYTHON COURSE, 2020) 
Construtor da classe: Deve ser chamado o construtor explicitamente das superclasses com o 
seguinte formato: nomeclasse.__init__(construtores) 
Execução no terminal: 
>>>from clientes import Cliente 
... from ContasClientesExtrato import Conta 
... from ContaPoupanca import Poupanca 
... from ContaRemuneradaPoupanca import ContaRemuneradaPoupanca 
... cliente1 = Cliente("123","Joao","Rua X") 
... cliente2 = Cliente ("456","Maria","Rua W") 
... conta1 = Conta([cliente1,cliente2],1,2000) 
... contapoupanca1 = Poupanca(0.1) 
... contarenumerada1 = ContaRemuneradaPoupanca(0.1,cliente1,5,1000,5) 
... contarenumerada1.remuneraConta() 
... contarenumerada1.geralsaldo() 
numero: 5 
 saldo: 998.3333333333334 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 118 
 
Polimorfismo 
Polimorfismo é o mecanismo que permite que um método com o mesmo nome seja executado de 
modo diferente, dependendo do objeto que está chamando o método. A linguagem define em tempo de 
execução (late binding) qual método deve ser chamado. Essa característica é bastante comum em herança 
de classes devido à redefinição da implementação dos métodos nas subclasses. 
Vamos assumir que agora teremos uma entidade Banco que controla todas as contas criadas no 
sistema de conta corrente. As contas podem ser do tipo conta, contacomum ou contarenumerada. O cálculo 
do rendimento da conta Cliente desconta IOF e IR; a conta Renumerada desconta apenas o IOF; a conta 
Cliente não tem desconto nenhum. Todos os descontos são realizados em cima do valor bruto após o 
rendimento mensal. Uma vez por vez o Banco executa o cálculo do rendimento de todos os tipos de contas. 
O diagrama é apresentado na Figura 42. 
 
Figura 42 - Diagrama Banco. Fonte: Estácio de Sá 
Vamos analisar agora a implementação das classes: 
class ContaCliente: 
 
def__init__(self, numero, IOF,IR,valorinvestido,taxarendimento): 
self.numero = numero 
self.IOF = IOF 
self.IR = IR 
self.valorinvestido = valorinvestido 
self.taxarendimento = taxarendimento 
 
def CalculoRendimento(self): 
self.valorinvestido += (self.valorinvestido * self.taxarendimento) 
self.valorinvestido = (self.valorinvestido – (self.taxarendimento * self.IOF* self.IR) 
 
def Extrato(Self): (1) 
print (f"O saldo atual da conta {self.numero} é {self.valorinvestido:10.2f}") 
Figura 43 - Classe ContaCliente. 
 
from ContaCliente import ContaCliente 
class ContaComum(ContaCliente) 
def__init__(self,numero,IOF,IR,valorinvestido,taxarendimento): 
super().__init__(numeroIOFIR,valorinvestido,taxarendimento) 
 
def CalculoRendimento(Self): (2) 
sef.valorinvestido += (self.valorinvestido* self.taxarendimento) 
Figura 44 - Classe ContaComum. 
 
from ContaCliente import ContaCliente 
class ContaRemunerada(ContaCliente): 
def__init__(self,numero,IOF,IR,valorinvestido,taxarendimento): 
super().__init__(numeroIOFIR,valorinvestido,taxarendimento) 
 
def CalculoRendimento(Self): (3) 
sef.valorinvestido += (self.valorinvestido * self.taxarendimento) 
sef.valorinvestido -= self.valorinvestido * self.IOF 
Figura 45 - Classe ContaCliente. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 119 
 
Em (1), foi definido um método Extrato que é igual para as 3 classes, ou seja, as subclasses herdarão 
o código completo desse método. Em (2) e (3), as subclasses possuem regras de negócios diferentes, 
portanto sobrescreveram o método CalculoRendimento para atender às suas necessidades. 
Vamos analisar a implementação da classe Banco e do programa que a utiliza: 
class Banco(): 
def__init__(self, codigo,nome): 
self.codigo = codigo 
self.nome = nome 
self.contas = [] 
 
def adicionaconta(self,contacliente): 
self.contas.append(contacliente) 
 
def calcularendimentomensal(self): (7) 
for c in self.contas: 
c.CalculoRendimento() 
def imprimesaldocontas(self): 
for c in self.contas: 
Figura 46 - Classe Banco. 
banco1 = Banco(999,"teste") 
contacliente1 = ContaCliente (1,0.01,0.1,1000,0.05) 
contacomum1 = ContaComum(2,0.01,0.1,2000,0.05) 
contaremunerada1 = ContaRemunerada(3,0.01,0.1,2000,0.05) 
 
banco1.adicionaconta(contacliente1) (4) 
banco1.adicionaconta(contacomum1) (5) 
banco1.adicionaconta(contaremunerada1) (6) 
banco1.calcularendimentomensal(7) 
banco1.imprimesaldocontas() (8) 
Figura 47 - Classe BancoContas. 
Em (4), (5) e (6), banco adiciona todas as contas da hierarquia em um único método devido ao teste 
“É-UM” das linguagens orientadas a objetos. No método, isso é definido para receber um objeto do 
tipo ContaCliente. Toda vez que o método é chamado, a linguagem testa se o objeto passado “É-
UM” objeto do tipo ContaCliente. 
Em (4), o objeto é da própria classe Conta Cliente. Em (5), o objeto contacomoum1 passado é uma 
ContaComum, que passa no teste “É-UM”, pois uma ContaComum é uma ContaCliente também. 
Em (6), o objeto contarenumerada1 “É-UM” objeto ContaComum. Essas ações são feitas de forma 
transparente para o programador. 
Em (7), acontece a “mágica” do Polimorfismo. Pois, em (4), (5) e (6) são adicionadas contas de 
diferentes tipos para o array conta da classe Banco. Assim, no momento da execução do método 
c.calculorendimentomensal(), o valor de c recebe, em cada loop, um tipo de objeto diferente da 
hierarquia da classe ContaCliente. Portanto, na instrução c.CalculoRendimento(), o interpretador 
tem que identificar dinamicamente de qual objeto da hierarquia Conta Cliente deve ser chamado o 
método CalculoRendimento. 
Em (8), acontece uma característica que vale ser ressaltada. Pelo polimorfismo, o interpretador irá 
verificar o teste “É-UM”, porém esse método não foi sobrescrito pelas subclasses da hierarquia 
ContaCliente. Portanto, será chamado o método Extrato da superclasse. 
Se executarmos a classe o programa banco_contarenumerada, o resultado será: 
O saldo atual da conta 1 é: 1048.95 
O saldo atual da conta 2 é: 2100.00 
O saldo atual da conta 3 é: 2079.00 
O polimorfismo é bastante interessante em sistemas com dezenas de subclasses herdeiras de uma 
única classe, assim todas as subclasses redefinem esse método. Sem o polimorfismo, haveria a 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 120 
 
necessidade de “perguntar” para a linguagem qual a instância do objeto em execução para chamar o método 
correto. Com base no polimorfismo, essa checagem é feita internamente pela linguagem de maneira 
transparente. 
Classes abstratas 
Definir uma classe abstrata é uma característica bastante utilizada pela programação orientada a 
objetos. Esse é um tipo de classe que não pode ser instanciado durante a execução do programa orientado 
a objetos, ou seja, não podem existir objetos dessa classe sendo executados na memória. O termo abstrato 
remete a um conceito do mundo real, considerando que preciso apenas de objetos concretos no programa. 
A classe abstrata se encaixa perfeitamente no problema do sistema de conta corrente do banco. 
Nesse sistema, o banco não quer tratar clientes do tipo ContaCliente, e sim apenas os objetos do tipo 
ContaComum e Conta VIP. 
 
Figura 48 - Diagrama de Classes abstratas. Fonte: Estácio de Sá 
Houve apenas adição de esteréotipo <<abstract>> para indicar que Conta Cliente é uma classe 
abstrata. 
O Python utiliza um módulo chamado abc para definir uma classe como abstrata, a qual será herdeira 
da superclasse ABC (Abstract Base Classes). Toda classe abstrata é uma subclasse da classe ABC 
(CAELUM, 2020). Para tornar a classe Conta Cliente abstrata, muda-se a definição para: 
from abc import ABC 
class ContaCliente(ABC): 
Figura 49 - Definição de classe abstrata. 
Para uma classe ser considerada abstrata, tem de ter pelo menos um método abstrato. Esse método 
abstrato pode ter implementação, embora não faça sentido, pois ele deverá, obrigatoriamente, ser 
implementado pelas subclasses. Em nosso exemplo, como não teremos o ContaCliente, esta conta não terá 
Calculo do rendimento. 
O decorator @abstractmethod indica para a linguagem que o método é abstrato (STANDARD 
LIBRARY, 2020), conforme o código apresentado na Figura 3.15: 
from abc import ABC, abstractmethod 
class ContaCliente(ABC) 
def__init__(self,sumero,IOF,IR,valorinvestido,taxarendimento): 
self.numero = numero 
self.IOF = IOF 
self.IR = IR 
self.valorinvestido = valorinvestido 
self.taxarendimento = taxarendimento 
@abstractmethod 
def CalculoRendimento(self): 
pass 
Figura 50 - Definição de método abstrato. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 121 
 
Quando se tentar instanciar um objeto da classe, obtém-se um erro indicando que essa classe não 
pode ser instanciada.. 
>>> from ContaClienteAbstrata import ContaCliente 
cc1 = ContaCliente(1,0.1,0.25,0.1) 
Traceback (most recent call last): 
File "<input>", line 2, in <module> 
TypeError: Can't instantiate abstract class ContaCliente with abstract methods CalculoRendimento 
Apenas as subclasses ContaComum e ContaVIP podem ser instanciadas. 
Atenção 
Um alerta importante é que as classes mencionadas devem, obrigatoriamente, implementar os métodos. Caso 
contrário, serão classes abstratas e delegarão para as suas subclasses a implementação concreta do método abstrato. 
Fica como sugestão criar as classes concretas ContaComum e ContaVIP sem implementar o método abstrato 
do superclasse ContaCliente. 
Exceções 
Como diversas linguagens orientadas a objetos, o Python permite criar novos tipos de exceções para 
diferenciar os erros gerados pelas bibliotecas da linguagem dos erros gerados pelas aplicações 
desenvolvidas. Devemos usar a característica da herança para herdar novas exceções a partir classe 
Exception do Python (MENEZES, 2020). 
class ExcecaoCustomizada(exception): (1) 
pass 
def throws(): (2) 
raise ExcecaoCustomizada 
try: (3) 
throws() 
except ExcecaoCustomizada as ex: 
print ("Excecao lançada") 
Figura 51 - Exceção customizada. 
No código acima: 
Em (1), definimos a exceção customizada ExcecaoCustomizada com o método pass, pois não 
executa nada relevante. 
Em (2), é definido um método que, se for chamado, cria a exceção na memória 
ExcecaoCustomizada. 
Em (3), é utilizado o try...except, que indica para o interpretador que a área do código localizada 
entre o try e o except poderá lançar exceções que deverão ser tratadas nas linhas de código após 
o except. 
Ao final da execução, será impresso “Exceção lançada” pela captura da exceção lançada pelo 
método throws(). 
Verificando o aprendizado 
1. Sobre a linguagem de programação PYTHON, marque a alternativa incorreta. 
A.Python suporta a maioria das técnicas da programação orientada a objetos. 
B. Python suporta e faz uso constante de tratamento de exceções como uma forma de testar condições 
de erro e outros eventos inesperados no programa. 
C. A linguagem Python permite a utilização do conceito de sobrecarga de métodos através do 
polimorfismo dos métodos. 
D. A separação de blocos de código em Phyton é feita utilizando a endentação de código. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 122 
 
A questão abrange uma visão geral sobre os conceitos de Orientação a Objetos implementados em Python. O 
Python não permite a sobrecarga de métodos nativamente. 
 
2. Em relação aos conceitos da orientação a objetos e à implementação em Python, podemos afirmar que: 
A. O Poliformismo permite a sobrecarga de métodos em uma classe Python. 
B. Objetos diferentes podem ser agrupados na mesma classe, sempre que tenham o mesmo número de 
bytes. 
C. Na linguagem Python existe o conceito de classes abstratas, que fornecem uma capacidade de 
reutilização para programas orientados a objetos. 
D. A linguagem Python implementa parcialmente herança múltipla através do poliformismo. 
A questão abrange uma visão geral a implementação dos conceitos orientados a objetos implementados em 
Python. Uma classe em Python pode representar um objeto abstrato do mundo real, pois esse possui propriedades e 
responsabilidades que serão utilizados por outros objetos da hierarquia no programa orientado a objetos. 
OO aplicados a Python com outras linguagens OO existentes no 
mercado 
Linguagem de programação orientadas a objetos 
As linguagens orientadas a objetos C++ e Java são bastante utilizadas assim como Python. Inclusive, 
estão em posições subsequentes no ranking das linguagens mais utilizadas de todos os paradigmas (TIO-
BE, 2020). Portanto, é interessante fazer um paralelo das principais características de cada linguagem em 
relação a orientada a objetos: Python (RAMALHO, 2020), C++ (C++, 2020) e Java (JAVA, 2020) 
Comparação com C++ e Java 
Instanciação de objetos 
As linguagens Java e C++ obrigam utilizar a palavra reservada new e indicar o tipo do objeto. Porém, 
a linguagem C++ referencia todos os objetos explicitamente através de ponteiros. Na tabela a seguir, o 
objeto Conta instanciado será referenciado pelo ponteiro *c1. A linguagem Python tem uma forma 
simplificada de instanciação de objetos. 
Java C++ Python 
Conta c1 = new Conta() Conta *c1 = new Conta() c1 = Conta() 
Tabela 3 - Instanciação de Objetos em Java/C++/Python. 
Construtores de objetos 
As linguagens Java e C++ exigem um método definido como público e com o mesmo nome da classe. 
O Python obriga ser um método privado __init__, conforme apresentado na tabela 4. 
Java C++ Python 
Utilizado um método público com o mesmo 
nome da classe sem tipo de retorno: Public 
Conta() 
Utilizado um método com o mesmo 
nome da classe sem tipo de retorno: 
Conta::Conta(void) 
Utilizando um método público com a 
obrigatoriedade da passagem do objeto com 
self: def __init__(self) 
Tabela 4 – Construtores de Objetos em Java/C++/Python. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 123 
 
Modificadores de acesso atributos 
As linguagens C++ e Python possuem apenas os modificadores público e privado para atributos. No 
entanto, ao contrário de Python, C++ e Java, garantem que um atributo definido como privado seja acessado 
estritamente pela própria classe. O Python permite burlar um atributo privado, conforme detalhado na Tabela 
5. 
Java C++ Python 
Possui os seguintes modificadores: 
public 
private 
protected 
default 
Possui os seguintes modificadores: 
public 
private 
Possui os seguintes modificadores: 
público 
privado – iniciado com “_” 
Modificador privado pode ser burlado e acessado diretamente 
Tabela 5 – Modificadores de acesso em atributos em Java/C++/Python. 
Herança múltipla de classes 
As linguagens C++ e Python implementam herança múltipla diretamente através de classes, 
enquanto Java implementa através de herança múltipla de interfaces. 
Java C++ Python 
Não implementa. Utiliza herança 
múltipla de interfaces para substituir 
essa característica. 
Implementa com a referência das classes 
herdadas na declaração da classe: 
Class ContaRemunerada: public Conta, 
public Poupanca) 
Implementa com a referência das classes 
herdadas na declaração da classe: 
class ContaRemuneradaPoupanca(Conta, 
Poupanca): 
Tabela 6 – Herança Múltipla em Java/C++/Python. 
Classes sem definição formal 
A linguagem Java implementa o conceito como classes anônimas. Todas as linguagens 
implementam o conceito de classes sem definição formal. 
Java C++ Python 
protected void Calcular(){ 
 class Calculo{ 
 private int soma; 
 public void setSoma(int soma) 
{ 
 this.soma = soma; 
 } 
 public int getSoma() { 
 return soma; 
 } 
 } 
} 
Existe o conceito de classes locais – 
internos a funções: 
void func() { 
 class LocalClass { 
 } 
} 
Existe o conceito de classes locais: 
def scope_test(): 
 def do_local(): 
 spam = "local spam" 
Tabela 7 – Classes informais em Java/C++/Python. 
Tipos primitivos 
As linguagens Java e C++ possuem um conjunto parecido de tipos primitivos, enquanto, em Python, 
todos as variáveis são definidas como objetos. 
Java C++ Python 
Possui vários tipos primitivos: 
int 
byte 
short 
long 
float 
double 
boolean 
char 
Possui vários tipos primitivos: 
bool 
char 
int 
float 
double 
void 
wchar_t 
Todas as variáveis são consideradas objetos: 
>>>5.__add__(3) 
8 
Tabela 8 - Tipos Primitivos em Java/C++/Python. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 124 
 
Interfaces 
As linguagens Java e C++ implementam interfaces simples e múltiplas, enquanto, em Python, não 
existe o conceito de interfaces. 
Java C++ Python 
Implementa interfaces simples e múltiplas: 
Simples - Class Funcionario implements Autenticavel 
Múltipla - Class Funcionario implements Autenticavel, 
Descontavel 
Implementa interfaces simples e múltiplas: 
Simples - Class Funcionario: public Autenticavel 
Múltipla - Class Funcionario: public Autenticavel, public 
Descontavel 
Não implementa 
Tabela 9 – Interfaces em Java/C++/Python. 
Sobrecarga de métodos 
As linguagens Java e C++ implementam sobrecarga de métodos nativamente, enquanto Python não 
implementa nativamente. 
Java C++ Python 
Implementa sobrecarga de métodos: 
calculaimposto(salario) 
calculaImposto(salario,IR) 
Implementa sobrecarga de métodos: 
calculaimposto(salario) 
calculaImposto(salario,IR) 
Não implementa 
Tabela 10 – Sobrecarga de métodos em Java/C++/Python. 
Tabela Comparativa 
A Tabela 11 apresenta um resumo das características das linguagens Java, C++ e Python. A 
linguagem Python não possui atributos privados, interfaces e sobrecarga de métodos, que são necessidades 
fundamentais para a construção de sistemas orientados a objetos robustos baseado em design patterns. 
Portanto, Java e C++ levam uma vantagem considerável para construção de sistemas puramente orientados 
a objetos. 
Por sua simplicidade, o Python vem crescendo como a primeira linguagem de programação ensinada 
na graduação e, devido a quantidade de bibliotecas estatísticas e frameworks web existentes, é utilizada 
para o desenvolvimento de algoritmos de Data Science e sistemas Web. 
Tabela 11 – Tabela Comparativa. 
Características Linguagens 
Java C++ Python 
Instanciação de objetos X X X 
Construtores de objetos X X X 
Modificadores de acesso atributos X X X(*) 
Modificadores de acesso métodos X X X 
Herança múltipla X X 
Classes informais X X 
Tipos primitivos X X 
Interfaces X X 
Sobrecarga de métodos X X 
(*) Pode ser burlado e ser acessado diretamente 
Verificando o aprendizado 
1. Em Python, como trabalhar sempre com tipos objetos: 
A. x = c + ADD(a+ b). 
B. obj(8).__. 
C. 5.__add__(3). 
D. sub(5).__add__(3). 
Na alternativa C, é realizada a soma seguindo a nota Python. A questão abrange o tratamento do Python em 
relação a todos os tipos serem considerados objetos. 
2. Analisando as características Orientada a Objetos de C++, Java e Python, consideramos as seguintes 
afirmações: 
I. Em Java, é permitida a criação de herança múltipla de classes através das classes denominadas interfaces 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 125 
 
II. Em Python, como em C++ e Java, existem os tipos primitivos e os objetos para serem utilizados pelos 
programas 
III. Em Python, o encapsulamento não segue os princípios da orientação a objetos 
 
A. II, apenas. 
B. II e III, apenas. 
C. I e II, apenas. 
D. III, apenas. 
Python não possui tipos privados. Os tipos privados que garantem o encapsulamento são em Java e C++. 
Considerações finais 
O paradigma orientado a objetos é largamente utilizado no mercado devido a facilidade na 
transformação de conceitos do mundo real para objetos implementados em uma linguagem de software. A 
linguagem Python implementa o paradigma utilizando uma sintaxe simples e robusta. Portanto, vem 
ganhando mercado, tanto na área acadêmica, quanto na área comercial, para o desenvolvimento de 
sistemas orientado a objetos. 
Outro ponto importante é que, devido a sua simplicidade, Python vem sendo utilizada como a primeira 
linguagem a ser aprendida nos primeiros períodos dos cursos de tecnologia e engenharia, inclusive para 
fixar os conceitos da orientação a objetos. 
A quantidade de bibliotecas opensource disponíveis para a implementação de algoritmos de Data 
Science tornou a linguagem importante para a implementação de sistemas de aprendizado e visualização 
de dados. 
Referências 
ANAYA, M. Clean Code in Python: Refactor Your Legacy Code Base. Packt Publishing Ltd, 29 ago. 
2018. 
CAELUM. Python e Orientação a Objetos. Consultado em meio eletrônico em: 14 jun. 2020. 
COSTA, M. Análise Orientada a Objetos, março de 2017, 100 f. Notas de Aula. 
FARINELLI, F. Conceitos básicos de programação orientada a objetos. Consultado em meio 
eletrônico em: 14 jun. 2020. 
GIRIDHAR, C. Learning Python Design Patterns. Packit Publishing, 2018. 
JAVA. Java Tutorial. Consultado em meio eletrônico em: 14 jun. 2020. 
MENEZES, N. C. Introdução a programação com Python. 3. ed. São Paulo: Novatec, 2019. 
PAJANKAR, A. Python Unit Test Automation: Practical Techniques for Python Developers and 
Testers. Apress, 2017. 
PYTHON COURSE, Blog Python. Consultado em meio eletrônico em: 14 jun. 2020. 
QCONCURSOS, Questões de Concursos. Consultado em meio eletrônico em: 18 jun. 2020. 
RAMALHO, L. Fluent Python. Sebastopol, CA: O´Reilly Media, 2015. 
RAMALHO, L. Introdução à Orientação a Objetos em Python (sem sotaque). Consultado em meio 
eletrônico em: 14 jun. 2020. 
REAL PYTHON, Blog Python, Consultado em meio eletrônico em: 14 jun. 2020. 
RUMBAUGH, J. et al. Modelagem e projetos baseados em objetos, Rio de janeiro: Campus, 1994. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 126 
 
STANDARD LIBRARY, The Python Standard Library. Consultado em meio eletrônico em: 24 jun. 
2020. 
TIO-BE. TIO-BE Index. Consultado em meio eletrônico em: 14 jun. 2020. 
TUTORIALSPOINT. C++ Tutorial. Consultado em meio eletrônico em: 14 jun. 2020. 
Explore+ 
Para saber mais sobre os assuntos tratados neste tema: 
O desenvolvimento de frameworks com metaclasses é um assunto importante e bastante utilizado 
no mercado. Para estudar um pouco mais esse tema, indicamos o livro Fluent Python, de Luciano Ramalho, 
publicado em 2015 pela O´Reilly Media. 
Os designs patterns devem ser estudados e aplicados em sistemas orientados a objetos de qualquer 
porte. Para se aprofundar nesse assunto, indicamos a obra Clean Clean Code in Python: Refactor Your 
Legacy Code Base, de Mariano Anaya, publicado em 2018 pela Packit Publishing e o livro Learning Python 
Design Patterns, de Giridhar publicado em 2018 Packit Publishing. 
Os testes unitários buscam garantir a qualidade da implementação de acordo com as regras de 
negócios. Para se aprofundar nesse assunto, indicamos a obra Python Unit Test Automation: Practical 
Techniques for Python Developers and Testers de Ashwin Pajankar publicado em 2017 pela Apress. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 127 
 
Python em Outros Paradigmas 
Introdução 
Neste tema, veremos a utilização da linguagem Python em outros paradigmas, como linguagem 
funcional, computação concorrente, desenvolvimento web e ciência de dados. 
Apesar do Python não ser uma linguagem puramente funcional, ela fornece ferramentas para que 
possamos programar utilizando esse paradigma. Neste tema, veremos como isso é possível e quais as 
vantagens desse estilo de programação. 
Vamos aprender também conceitos relacionados à computação concorrente e à computação 
paralela, suas diferenças e como podem ser implementadas em Python. 
Embora o Python não seja a primeira escolha como linguagem de programação para servidores web, 
é possível encontrar diversos frameworks que facilitam, e muito, a sua utilização para tal finalidade. Alguns 
são minimalistas, como o — Flask — e permitem criar servidores web escritos em Python em minutos. 
Em contrapartida, essa linguagem de programação é a escolha número 1 para a ciência de dados. 
Neste tema, iremos conhecer um pouco sobre o processo de extração de conhecimento e como implementá-
lo em Python utilizando a biblioteca Scikit-Learn. 
Linguagem funcional e sua utilização em Python 
Introdução 
A programação funcional teve seu início no final dos anos 1950, com a linguagem LISP. 
À diferença do que muitos pensam, esse tipo de programação não é apenas a utilização de funções 
em seu código-fonte, mas um paradigma e um estilo de programação. 
Na programação funcional, toda ação realizada pelo programa deve ser implementada como uma 
função ou uma composição de funções, mas estas devem seguir algumas regras: 
1. Devem ser puras, ou seja, em qualquer ponto do programa, sempre produzem o mesmo 
resultado quando passados os mesmos parâmetros; 
2. Os dados devem ser imutáveis, e uma vez definida uma variável, seu valor não pode ser 
alterado; 
3. Os loops não devem ser utilizados, mas sim a composição de funções ou recursividade. 
A utilização dessas regras visa garantir, principalmente, que não haja um efeito indesejável e 
imprevisto quando executamos um programa ou parte dele. 
Muitas linguagens de programação (como Python, Java e C++) dão suporte para a programação 
funcional, porém são de propósito geral, dando base para outros paradigmas, como programação imperativa 
e orientada a objetos. 
Outras linguagens, como Haskell, Clojure e Elixir, são predominantemente de programação 
funcional. 
A seguir, ensinaremos como utilizar o Python para programação funcional. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 128 
 
Funções puras 
São aquelas que dependem apenas dos parâmetros de entrada para gerar uma saída. Elas sempre 
retornam um valor, um objeto ou outra função. Em qualquer ponto do programa, ao chamar uma função 
pura, com os mesmos parâmetros, devemos obter sempre o mesmo resultado. 
Veja os dois scripts, funcao1.py e funcao2.py, no Codigo 1 seguir: 
Codigo 1 - Scripts funcao1.py 
1 valor = 20 
2 
3 def multiplica(fator): 
4 global valor 
5 valor = valor * fator 
6 print("Resultado", valor) 
7 
8 multiplica(3) 
9 multiplica(3) 
Codigo 1 - Scripts funcao2.py 
1 valor = 20 
2 
3 def multiplica(valor, fator): 
4 valor = valor * fator 
5 return valor 
6 
7 print("Resultado", multiplica(valor, 3)) 
8 print("Resultado", multiplica(valor, 3)) 
 
SCRIPT 1 
funcao1.py, definimos uma função chamada multiplica, que multiplica a variável global valor por umfator passado como parâmetro. O valor do resultado é atribuído à variável valor novamente (linha 
5), que é impresso em seguida (linha 6). 
Ao chamarmos a função multiplica(3) pela primeira vez (linha 8), obtemos a saída “Resultado 60”. 
Como modificamos a própria variável global valor no corpo da função, ao chamarmos novamente a 
função multiplica(3) (linha 9), obtemos um resultado diferente para a saída: “Resultado 180”. 
Além de não depender apenas dos parâmetros, essa função não retorna valor algum. A função 
multiplica deste script não é pura. 
SCRIPT 2 
funcao2.py, utilizamos a variável valor como mais um parâmetro para a função multiplica. As duas 
vezes que executamos essa função (linha 7 e 8), elas retornam o mesmo valor, 60. 
A função multiplica deste script é um exemplo de função pura, pois depende apenas de seus 
parâmetros para gerar o resultado, e não acessa ou modifica nenhuma variável externa à função e 
retorna um valor. 
Dados imutáveis 
São aqueles que não podem ser alterados após sua criação. Apesar do Python disponibilizar algumas 
estruturas de dados imutáveis, como as tuplas, a maioria é mutável. Na programação funcional, devemos 
tratar todos os dados como imutáveis! 
As funções puras devem utilizar apenas os parâmetros de entrada para gerar as saídas. Além dessa 
característica, as funções puras não podem alterar nenhuma variável fora de seu escopo. 
Observe os scripts do Codigo 2 a seguir, em que passamos a lista valores como argumento para a 
função altera_lista. Lembre-se que, no Python, ao passar uma lista como argumento, apenas passamos sua 
referência, ou seja, qualquer mudança feita no parâmetro dentro da função, também altera a lista original. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 129 
 
Codigo 2 - Scripts funcao3.py 
1 valores = [10, 20, 30] 
2 
3 def altera_lista(lista): 
4 lista[2] = lista[2] + 10 
5 return lista 
6 
7 print("Nova lista", altera_lista(valores)) 
8 print("Nova lista", altera_lista(valores)) 
 Codigo 2 - Scripts funcao4.py 
1 valores = [10, 20, 30] 
2 
3 def altera_lista(lista): 
4 nova_lista = list(lista) 
5 nova_lista[2] = nova_lista[2] + 10 
6 return nova_lista 
7 
8 print("Nova lista", altera_lista(valores)) 
9 print("Nova lista", altera_lista(valores)) 
Na programação funcional, devemos evitar alterar qualquer dado que já tenha sido criado. No 
exemplo anterior, no script funcao3.py, ao alterar o terceiro elemento do parâmetro lista (linha 4), alteramos 
também a variável global valores. 
Com isso, ao chamar a mesma função duas vezes (linha 7 e 8), com, teoricamente, o mesmo 
parâmetro, obtemos um efeito indesejável, resultando em saídas diferentes, como no Codigo 3. 
Codigo 3 - Saída do script funcao3.py 
1 C:\Users\ftoli\PycharmProjects\estac 
2 Nova lista [10, 20, 40] 
3 Nova lista [10, 20, 50] 
4 
5 Process finished with exit code 0 
No exemplo do script funcao4.py, muito similar ao anterior, ao invés de alterarmos o valor do próprio 
parâmetro, criamos uma cópia dele (linha 4), sendo assim, não alteramos a variável valores e obtemos o 
mesmo resultado para as duas chamadas da função (linha 8 e 9). 
A saída desse script está no Codigo 4. 
Codigo 4 - Saída do script funcao4.py 
1 C:\Users\ftoli\PycharmProjects\estac 
2 Nova lista [10, 20, 40] 
3 Nova lista [10, 20, 40] 
4 
5 Process finished with exit code 0 
Efeito colateral e estado da aplicação 
As funções puras e dados imutáveis buscam evitar os efeitos indesejáveis, como ocorreu no script 
funcao3.py. Na terminologia de programação funcional, chamamos isso de efeito colateral (side effect). Além 
de evitar o efeito colateral, a programação funcional evita a dependência do estado de um programa. 
A dependência apenas dos parâmetros para gerar saídas garante que o resultado será sempre o 
mesmo, independentemente do estado da aplicação, por exemplo, valores de outras variáveis. Ou seja: não 
teremos diferentes comportamentos para uma função baseado no estado atual da aplicação. 
Dica 
Ao garantir que uma função utilizará apenas os dados de entrada para gerar um resultado e que nenhuma 
variável fora do escopo da função será alterada, temos a certeza de que não teremos um problema escondido, ou 
efeito colateral em nenhuma outra parte do código. 
O objetivo principal da programação funcional não é utilizar funções puras e dados imutáveis, mas 
sim evitar o efeito colateral. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 130 
 
Funções de ordem superior 
Na programação funcional, é muito comum utilizar funções que aceitem outras funções, como 
parâmetros ou que retornem outra função. 
Essas funções são chamadas de funções de ordem superior (higher order function). 
No exemplo do Codigo 5 a seguir, vamos criar uma função de ordem superior chamada 
multiplicar_por. Ela será utilizada para criar e retornar novas funções. 
Essa função, ao ser chamada com um determinado multiplicador como argumento, retorna uma nova 
função multiplicadora por aquele multiplicador e que tem como parâmetro o número a ser multiplicado 
(multiplicando). 
Codigo 5 - Scripts funcao5.py 
1 def multiplicar_por(multiplicador): 
2 def multi(multiplicando): 
3 return multiplicando * multiplicador 
4 return multi 
5 
6 multiplicar_por_10 = multiplicar_por(10) 
7 print(multiplicar_por_10(1)) 
8 print(multiplicar_por_10(2)) 
9 
10 multiplicar_por_5 = multiplicar_por(5) 
11 print(multiplicar_por_5(1)) 
12 print(multiplicar_por_5(2)) 
Dentro da função “pai” multiplicar_por, definimos a função multi (linha 2), que espera um parâmetro 
chamado multiplicando, que será multiplicado pelo multiplicador passado como parâmetro para a função 
“pai”. 
Ao chamar a função multiplicar_por com o argumento 10 (linha 6), definimos a função interna multi 
como: 
def multi(multiplicando): 
return multiplicando * 10 
Essa função é retornada e armazenada na variável multiplicar_por_10 (linha 6), que nada mais é que 
uma referência para a função multi recém-criada. 
Dessa forma, podemos chamar a função multiplicar_por_10, passando um número como argumento, 
o multiplicando, para ser multiplicado por 10 (linha 7 e 8). Produzindo os resultados 10 e 20. 
Da mesma forma, criamos a função multiplicar_por_5, passando o número 5 como argumento para 
a função multiplicar_por (linha 10), que recebe uma referência para a função: 
def multi(multiplicando): 
‘return multiplicando * 5 
Com isso, podemos utilizar a função multiplicar_por_5 para multiplicar um número por 5 (linhas 11 e 
12). 
Observe a saída do programa no console abaixo. 
Codigo 5 - Saída do script funcao5 
1 C:\Users\fotoli\PycharmProjects\estac 
2 10 
3 20 
4 5 
5 10 
6 
7 Process finished with exit code 0 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 131 
 
Funções lambda 
Assim como em outras linguagens, o Python permite a criação de funções anônimas. Estão são 
definidas sem identificador (ou nome) e, normalmente, são utilizadas como argumentos para outras funções 
(de ordem superior). 
Em Python, as funções anônimas são chamadas de funções lambda. Para criá-las, utilizamos a 
seguinte sintaxe: 
lambda argumentos: expressão 
Iniciamos com a palavra reservada lambda, seguida de uma sequência de argumentos separados 
por vírgula, dois pontos e uma expressão de apenas uma linha. As funções lambda SEMPRE retornam o 
valor da expressão automaticamente. Não é necessário utilizar a palavra return. 
Exemplo 
Considere a função para multiplicar dois números a seguir: 
def multiplicar(a, b): 
return a*b 
A função lambda equivalente é: 
lambda a, b: a*b 
Temos os parâmetros a e b e a expressão a*b, que é retornado automaticamente. As funções lambda 
podem ser armazenadas em variáveis para depois serem chamadas como uma função qualquer. 
Retornando ao exemplo da função multiplicar_por, podemos trocar a função multi poruma função 
lambda. Observe no Codigo 6, a seguir, em que abaixo (anonima.py), temos a utilização da função lambda 
e após a utilização da função original (funcao5.py): 
Codigo 6 - Script anonima.py 
01 def multiplicar_por(multiplicador): 
02 return lambda multiplicando: multiplicando * multiplicador 
03 
04 multiplicar_por_10 = multiplicar_por(10) 
05 print(multiplicar_por_10(1)) 
06 print(multiplicar_por_10(2)) 
07 
08 multiplicar_por_5 = multiplicar_por(5) 
09 print(multiplicar_por_5(1)) 
10 print(multiplicar_por_5(2)) 
 
Codigo 6 - Script funcao5.py 
01 def multiplicar_por(multiplicador): 
02 def multi(multiplicando): 
03 return multiplicando * multiplicador 
04 return multi 
05 
06 multiplicar_por_10 = multiplicar_por(10) 
07 print(multiplicar_por_10(1)) 
08 print(multiplicar_por_10(2)) 
09 
10 multiplicar_por_5 = multiplicar_por(5) 
11 print(multiplicar_por_5(1)) 
12 print(multiplicar_por_5(2)) 
Ao executar o script anonima.py, obtemos o mesmo resultado mostrado anteriormente: 10, 20, 5 e 
10. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 132 
 
Não utilizar loops 
Outra regra, ou boa prática, da programação funcional é não utilizar laços (for e while), mas sim 
composição de funções ou recu1rsividade. 
A função lambda exerce um papel fundamental nisso, como veremos a seguir. 
Para facilitar a composição de funções e evitar loops, o Python disponibiliza diversas funções e 
operadores. 
As funções internas mais comuns são map e filter. 
Map 
A função map é utilizada para aplicar uma determinada função em cada elemento de um iterável 
(lista, tupla, dicionários etc.), retornando um novo iterável com os valores modificados. 
A função map é pura e de ordem superior, pois depende apenas de seus parâmetros e recebe uma 
função como parâmetro. A sua sintaxe é a seguinte: 
map(função, iterável1, iterável2...) 
O primeiro parâmetro da map é o nome da função (sem parênteses) que será executada para cada 
item do iterável. Os demais parâmetros são os iteráveis separados por vírgula. A função map SEMPRE 
retorna um novo iterável. 
No exemplo do Codigo 7, a seguir, vamos criar três scripts. Todos executam a mesma operação. 
Recebem uma lista e triplicam cada item, gerando uma nova lista com os valores triplicados. 
Codigo 7 - Script funcao_iterable.py 
01 lista = [1, 2, 3, 4, 5] 
02 
03 def triplica_itens(iterable): 
04 lista_aux = [] 
05 for item in iterable: 
06 lista_aux.append(item*3) 
07 return lista_aux 
08 
09 nova_lista = triplica_itens(lista) 
10 print(nova_lista) 
 
Codigo 7 - Script funcao_map.py 
1 lista = [1, 2, 3, 4, 5] 
2 
3 def triplica(item): 
4 return item * 3 
5 
6 nova_lista = map(triplica, lista) 
7 print(list(nova_lista)) 
 
Codigo 7 - Script funcao_map_lambda.py 
1 lista = [1, 2, 3, 4, 5] 
2 
3 nova_lista = map(lambda item: item * 3, lista) 
4 print(list(nova_lista)) 
Primeiro Script 
funcao_iterable.py, definimos uma função chamada triplica_item, que recebe um iterável como 
parâmetro (linha 3), cria uma lista auxiliar para garantir imutabilidade (linha 4), percorre os itens do 
iterável passado como parâmetro (linha 5), adiciona os itens triplicados à lista auxiliar (linha 6) e 
retorna a lista auxiliar (linha 7). 
Essa função é chamada com o argumento lista (linha 9) e o resultado é impresso (linha 10). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 133 
 
Segundo Script 
funcao_map.py, definimos a função triplica, que triplica e retorna o item passado como parâmetro 
(linha 3 e 4). É utilizada, assim como a variável lista, como argumentos para a função map (linha 
6). 
A map vai aplicar internamente a função passada como parâmetro em cada item da lista, retornando 
um novo iterável (que pode ser convertido em listas, tuplas etc.). O resultado da função map é 
armazenado na variável nova_lista, para então ser impresso (linha 7). 
A função map garante a imutabilidade dos iteráveis passados como argumento. Como a função 
map retorna um iterável, utilizamos o construtor list(iterável) para imprimir o resultado (linha 7). 
Terceiro Script 
funcao_map_lambda.py, substituímos a função triplica pela função lambda (lambda item: item*3), 
que foi utilizada como argumento para a função map (linha 3). Esta vai aplicar a função lambda em 
cada item da lista, retornando um novo iterável que foi impresso posteriormente (linha 4). 
Observe como o código foi reduzido e mesmo assim preservamos a utilização de funções puras 
(lambda), alta ordem (map) e que preservaram a imutabilidade dos dados. Tudo isso para garantir 
que não haja efeitos colaterais e dependência de estados. 
Todos os scripts utilizam funções puras e geraram o mesmo resultado: [3, 6, 9, 12, 15]. 
Filter 
É utilizada para filtrar elementos de um iterável (lista, tupla, dicionários etc.). O filtro é realizado 
utilizando uma função, que deve ser capaz de retornar true ou false para cada elemento do iterável. 
Atenção 
Todo elemento que for avaliado como true será incluído em um novo iterável retornado pela função filter, que 
é pura e de alta ordem, pois depende apenas dos parâmetros e recebe uma função como parâmetro. A sua sintaxe é 
a seguinte: 
filter(função, iterável) 
 
O primeiro parâmetro da função filter é o nome da função (sem parênteses), que será executada para 
cada item do iterável. O segundo parâmetro é o iterável. A função filter SEMPRE retorna um novo iterável, 
mesmo que vazio. 
No exemplo do Codigo 8 a seguir, vamos criar três scripts. Todos fazem a mesma filtragem. Recebem 
uma lista e retornam os elementos ímpares, gerando uma nova lista, de forma a garantir a imutabilidade. 
Codigo 8 - Script funcao_filtro_iterable.py 
01 lista = [1, 2, 3, 4, 5] 
02 
03 def impares(iterable): 
04 lista_aux = [] 
05 for item in iterable: 
06 if item % 2 != 0: 
07 lista_aux.append(item) 
08 return lista_aux 
09 
10 nova_lista = impares(lista) 
11 print(nova_lista) 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 134 
 
Codigo 8 - Script funcao_filter.py 
1 lista = [1, 2, 3, 4, 5] 
2 
3 def impar(item): 
4 return item % 2 != 0 
5 
6 nova_lista = filter(impar, lista) 
7 print(list(nova_lista)) 
 
Codigo 8 - Script funcao_filter_lambda.py 
1 lista = [1, 2, 3, 4, 5] 
2 
3 nova_lista = filter(lambda item: item % 2 != 0, lista) 
4 print(list(nova_lista)) 
 
Script FUNÇÃO_FILTRO_ITERABLE.PY 
Definimos uma função chamada ímpares, que recebe um iterável como parâmetro (linha 3), cria uma 
lista auxiliar para garantir imutabilidade (linha 4), percorre os itens do iterável passados como parâmetros 
(linha 5), adiciona os itens ímpares à lista auxiliar (linha 6 e 7) e retorna a lista auxiliar (linha 8). 
Essa função é chamada com o argumento lista (linha 10) e o resultado é impresso (linha 11). 
Script FUNCAO_FILTER.PY 
Definimos a função ímpar, que retorna true se o item passado como parâmetro é ímpar ou false caso 
contrário (linha 3 e 4). Utilizamos essa função, assim como a variável lista, como argumentos para a função 
filter (linha 6). 
A filter vai aplicar, internamente, a função passada como parâmetro em cada item da lista, retornando 
um novo iterável (que pode ser convertido em listas, tuplas etc.). O resultado da função filter é armazenado 
na variável nova_lista, para então ser impresso (linha 7). 
A função filter garante a imutabilidade dos iteráveis passados como argumento. Como a função filter 
retorna um iterável, utilizamos o construtor list(iterável) para imprimir o resultado (linha 7). 
Script, FUNÇÃO_FILTER_LAMBDA.PY 
Substituímos a função ímpar pela função lambda (lambda item: item%2 != 0) que foi utilizada como 
argumento para a função filter (linha 3). Esta vai aplicar a função lambda em cada item da lista, retornando 
um novo iterável que foi impresso posteriormente (linha 4). 
Todos os scripts geraram o mesmo resultado:[1, 3, 5]. 
Verificando o aprendizado 
1. Observe as afirmativas relacionadas à programação funcional e responda. 
I - As funções puras sempre produzem o mesmo resultado quando passados os mesmos parâmetros. 
II - Dados imutáveis são aqueles nos quais seus valores podem ser alterados após a sua definição. 
III - Não se deve utilizar loops, mas composição de funções. 
IV - A programação funcional é um paradigma e um estilo de programação. 
Das afirmativas anteriores, quais são verdadeiras? 
A. II e III. 
B. I e III. 
C. II. 
D. I, III e IV. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 135 
 
Qual é o resultado impresso pelo programa a seguir? 
Script lambda1.py 
 
minha_funcao = lambda x: x ** 2 
resultado = minha_funcao(4) 
print(resultado) 
A. 4. 
B. 8. 
C. 16. 
D. 32. 
Computação concorrente e sua utilização em Python 
Introdução 
No início do ano 2000, poucas pessoas tinham acesso a computadores com mais de um processador. 
Além disso, os processadores dos desktops e notebooks daquela época continham apenas um núcleo, ou 
seja, só podiam executar uma operação por vez. 
Atualmente, é raro ter um computador, ou até mesmo um celular, com um processador de apenas 
um núcleo. Com isso, é muito importante aprendermos alguns conceitos sobre programação concorrente 
e paralela e como implementá-los, de forma a extrair o máximo de performance dos nossos programas. 
O dicionário on-line, DICIO, define a palavra “concorrente” como: “Simultâneo; o que acontece ao mesmo 
tempo que outra coisa [...]”. 
Na computação, temos dois conceitos relacionados à execução simultânea, concorrência e 
paralelismo, que serão apresentados no decorrer deste módulo. 
A seguir, definiremos alguns conceitos relacionados à computação concorrente e paralela, e, 
posteriormente, mostraremos como o Python implementa tais funcionalidades. 
Conceitos 
Programas e processos 
Os conceitos iniciais que precisamos definir são programas e processos. Mas o que seria um 
programa e um processo na visão do sistema operacional? 
Programa é algo estático e permanente. Contém um conjunto de instruções e é percebido pelo 
sistema operacional como passivo. 
Em contrapartida, o processo é dinâmico e tem uma vida curta. Ao longo da sua execução, tem seu 
estado alterado. Ele é composto por código, dados e contexto. Em suma, o processo é um programa em 
execução. 
O mesmo programa executado mais de uma vez gera processos diferentes, que contêm dados e 
momento de execução (contexto) também diferentes. 
Concorrência e paralelismo 
Em computação, o termo concorrente se refere a uma técnica para tornar os programas mais usáveis. 
Ela pode ser alcançada mesmo em processadores de apenas um núcleo, pois permite compartilhar o 
processador de forma a rodar vários processos. Os sistemas operacionais multitarefas suportam 
concorrência. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 136 
 
Exemplo 
Por exemplo, é possível compactar um arquivo e continuar usando o processador de texto, mesmo em um 
processador de um núcleo, pois o processador divide o tempo de uso entre os processos dessas duas aplicações. Ou 
seja: essas duas aplicações executam de forma concorrente. 
Apesar da concorrência não necessariamente precisar de mais de um núcleo, ela pode se beneficiar 
se houver mais deles, pois os processos não precisarão compartilhar tempo de processador. 
Já o paralelismo é uma técnica para permitir que programas rodem mais rápido, executando várias 
operações ao mesmo tempo. Ela requer várias máquinas ou um processador com mais de um núcleo. 
Também é possível realizar o paralelismo nas placas de vídeo. 
Threads e processos 
Relembrando 
O processo é uma instância de um programa em execução. Ele é composto pelo código que está sendo 
executado, os dados utilizados pelo programa (exemplo: valores de variável) e o estado ou contexto do processo. 
Em um programa com múltiplos processos, cada um tem seu próprio espaço de memória e cada um 
pode executar em um núcleo diferente, melhorando consideravelmente a performance do programa. 
Você sabia? 
A thread pertence a um determinado processo. Múltiplas threads podem ser executadas dentro de um mesmo 
processo. As de um mesmo processo compartilham a área de memória e podem acessar os mesmos dados de forma 
transparente. 
Em Python, podemos criar tanto processos quanto threads em um programa. 
Antes de falarmos sobre cada abordagem em Python, vamos falar sobre o global interpreter lock 
(GIL). No CPython — que é a implementação principal da linguagem de programação Python, escrita em 
linguagem C — o GIL existe para proteger o acesso aos objetos da linguagem. 
Isso acontece objetivando a prevenção para que múltiplas threads não possam executar os 
bytecodes do Python de uma vez. Essa “trava” é necessária, pois visa garantir a integridade do interpretador, 
uma vez que o gerenciamento de memória no CPython não é thread-safe. 
Na prática, para um mesmo processo, o GIL só permite executar uma thread de cada vez, ou seja, 
elas não executam de forma paralela, mas concorrentes. Sem a “trava” do GIL, uma operação 
simples de atribuição de variável poderia gerar um dado inconsistente caso duas threads 
atribuíssem um valor a uma mesma variável ao mesmo tempo. 
Para os processos, por sua vez, o funcionamento é diferente. Para cada um, temos um GIL separado. 
Ou seja: podem ser executados paralelamente. Cabe ao programador garantir o acesso correto aos dados. 
Múltiplos processos podem rodar em paralelo, enquanto múltiplas threads (de um mesmo processo) 
podem rodar concorrentemente. 
Atenção 
Normalmente, utilizamos thread para interface gráfica, acesso ao banco de dados, acesso à rede etc., pois o 
programa não pode parar, ou a interface congelar, enquanto esperamos baixar um arquivo, por exemplo. 
Porém, quando temos um programa que necessita muito dos recursos do processador e temos como 
paralelizar nosso programa, devemos optar pela criação de múltiplos processos. 
Criar novos processos pode ser lento e consumir muita memória, enquanto a criação de threads é 
mais rápida e consome menos memória. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 137 
 
Criação de threads e processos 
Exemplo 
Como criar threads e processos em Python: 
Vamos utilizar a classe thread e process, dos módulos threading e multiprocessing, respectivamente. Para 
facilitar a transição entre processos e threads simples, o Python fez os construtores e métodos das duas classes muito 
parecidos. 
No script principal.py do Codigo 9, vamos criar uma thread e um processo que executam a mesma 
função. Na linha 8, criamos uma thread para executar a função funcao_a utilizando a classe thread. O 
construtor tem como parâmetros a função que deverá ser executada (target) e quais parâmetros serão 
passados para essa função (args). O parâmetro args espera um iterável (lista, tupla etc.), onde cada 
elemento será mapeado para um parâmetro da função target. 
Como a funcao_a espera apenas um parâmetro, definimos uma tupla de apenas um elemento 
(‘Minha Thread”). O primeiro elemento da tupla, a string Minha Thread, será passada para o parâmetro nome 
da funcao_a. 
Na linha 9, enviamos o comando para a thread iniciar sua execução, chamando o método start() do 
objeto t do tipo thread. 
Codigo 9 - Script principal.py 
01 from threading import Thread 
02 from multiprocessing import Process 
03 
04 def funcao_a(nome): 
05 print(nome) 
06 
07 if __name__ == '__main__': 
08 t = Thread(target=funcao_a, args=("Minha Thread",)) 
09 t.start() 
10 
11 p = Process(target=funcao_a, args=("Meu Processo",)) 
12 p.start() 
 
A criação do processo é praticamente igual, porém utilizando a classe process, conforme a linha 11. 
Para iniciar o processo, chamamos o método start() na linha 12. 
Verifique a saída desse script no console abaixo.Codigo 9 - Saída do script principal(1) 
1 C:\Users\ftoli\PycharmProjects\estac 
2 Minha Thread 
3 Meu Processo 
4 
5 Process finished with exit code 0 
 
Múltiplas threads e processos 
No exemplo do Codigo 10 a seguir, vamos criar múltiplas threads e processos usando na criação de 
para criar threads e processos para compararmos as saídas de cada um. 
Vamos aproveitar para mostrar que todas as threads estão no mesmo contexto, com acesso às 
mesmas variáveis, enquanto o processo não. Vamos mostrar, também, como fazer o programa aguardar 
que todas as threads e processos terminem antes de seguir a execução. 
Atenção 
Observe que os códigos dos scripts são praticamente idênticos, com exceção das classes construtoras thread 
e process na linha 16 dos dois scripts. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 138 
 
Neste exemplo, a função que será paralelizada é a funcao_a (linha 7). Ela contém um laço que é 
executado cem mil vezes e para cada iteração adiciona o elemento 1 à lista minha_lista, definida 
globalmente na linha 5. 
Vamos criar 10 threads (e processos) para executar 10 instâncias dessa função, na qual, esperamos 
que o número de elementos na lista ao final da execução do programa seja de 1 milhão (10 threads X cem 
mil iterações). 
Para criar essas 10 threads ou processos, temos um laço de 10 iterações (linha 15), em que criamos 
(linha 16) e iniciamos (linha 18) cada thread ou processo. 
O objetivo da criação de threads ou processos é justamente a computação concorrente ou paralela, 
o Python não fica “parado” aguardando dela após chamar o método start(), ele imediatamente 
começa a próxima iteração do laço for. 
Codigo 10 - Script threads_var.py 
01 from threading import Thread, Lock 
02 from multiprocessing import Process 
03 import time 
04 
05 minha_lista = [] 
06 
07 def funcao_a(indice): 
08 for i in range(100000): 
09 minha_lista.append(1) 
10 print("Termino thread ", indice) 
11 
12 if __name__ == '__main__': 
13 tarefas = [] 
14 for indice in range(10): 
15 tarefa = Thread(target=funcao_a, args=(indice,)) 
16 tarefas.append(tarefa) 
17 tarefa.start() 
18 
19 print("Antes de aguardar o termino!", len(minha_lista)) 
20 
21 for tarefa in tarefas: 
22 tarefa.join() 
23 
24 print("Após aguardar o termino!", len(minha_lista)) 
 
Codigo 10 - Script processos_var.py 
01 from threading import Thread, Lock 
02 from multiprocessing import Process 
03 import time 
04 
05 minha_lista = [] 
06 
07 def funcao_a(indice): 
08 for i in range(100000): 
09 minha_lista.append(1) 
10 print("Termino processo ", indice) 
11 
12 if __name__ == '__main__': 
13 tarefas = [] 
14 for indice in range(10): 
15 tarefa = Process(target=funcao_a, args=(indice,)) 
16 tarefas.append(tarefa) 
17 tarefa.start() 
18 
19 print("Antes de aguardar o termino!", len(minha_lista)) 
20 
21 for tarefa in tarefas: 
22 tarefa.join() 
23 
24 print("Após aguardar o termino!", len(minha_lista)) 
 
Atenção 
É função do programador armazenar uma referência para as suas threads ou processos, de maneira que 
possamos verificar seu estado ou interrompê-las. Para isso, armazenamos cada thread ou processo criado em uma 
lista chamada tarefas (linha 17). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 139 
 
Logo após a criação das threads ou processos, vamos imprimir o número de itens na variável 
minha_lista (linha 20); aguardar o término da execução das threads ou processos pela iteração da lista 
tarefas e utilizando o método join() (linha 22 e 23); e, por fim, imprimimos o número de itens final da variável 
minha_ lista (linha 25). 
No Codigo 11, a seguir, temos o resultado de cada script. 
Codigo 11 - Saída do script threads_var.py 
01 C:\Users\ftoli\PycharmProjects\estacio_ead\venv\Scripts\python.e 
02 Termino thread Termino thread 0 1 
03 
04 Termino thread Termino thread 23Termino thread 4 
05 
06 Termino thread 5 
07 Termino thread 6 
08 Termino thread 7 
09 Termino thread Antes de guardar o termino! Termino thread 9 
10 970012 
11 8 
12 Apos guardar o termino! 1000000 
13 
14 Process finished with exit code 0 
 
Codigo 11 - Saída do script processos_var.py 
01 C:\Users\ftoli\PycharmProjects\estacio_ead\venv\ 
02 Antes guardar o termino! 0 
03 Termino thread 0 
04 Termino thread 2 
05 Termino thread 1 
06 Termino thread 4 
07 Termino thread 3 
08 Termino thread 5 
09 Termino thread 7 
10 Termino thread 6 
11 Termino thread 8 
12 Termino thread 9 
13 Apos guardar o termino! 0 
14 
15 Process finished with exit code 0 
 
Apesar da saída do script thread.py ter ficado confusa (já iremos retornar nesse problema), observe 
que o número de itens da variável minha_lista muda durante a execução do programa quando usamos 
thread e não muda quando usamos processos. 
Isso acontece, pois a área de memória das threads é compartilhada, ou seja, elas têm acesso às 
mesmas variáveis globais. Em contrapartida, as áreas de memória dos processos não são compartilhadas. 
Cada processo acaba criando uma versão própria da variável minha_lista. 
Travas (Lock) 
No exemplo anterior, a função funcao_a incluía o elemento 1 à lista a cada iteração, utilizando o 
método append(). No exemplo a seguir, a funcao_a irá incrementar a variável global contador. Observe o 
código do Codigo 12 e verifique o resultado impresso no console seguinte. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 140 
 
Codigo 12 - Script threads_inc.py 
01 from threading import Thread, Lock 
02 from multiprocessing import Process 
03 import time 
04 
05 contador = 0 
06 
07 def funcao_a(indice): 
08 global contador 
09 for i in range(1000000): 
10 contador += 1 
11 print("Termino thread ", indice) 
12 
13 if __name__ == '__main__': 
14 tarefas = [] 
15 for indice in range(10): 
16 tarefa = Thread(target=funcao_a, args=(indice,)) 
17 tarefas.append(tarefa) 
18 tarefa.start() 
19 
20 print("Antes de aguardar o termino!", contador) 
21 
22 for tarefa in tarefas: 
23 tarefa.join() 
24 
25 print("Após aguardar o termino!", contador) 
 
Codigo 12 - Saída do script threads_inc 
01 C:\Users\ftoli\PycharmProjects\estacio_ead\venv\S 
02 Termino thread 1 
03 Termino thread Termino thread 3 2 
04 
05 Termino thread 0 Termino thread 
06 Antes de aguardar o termino! Termino thread 4 
07 5Termino thread 6 
08 2235554 
09 
10 Termino thread Termino thread 9 
11 Termino thread 7 
12 8 
13 Apos aguardar o termino! 3316688 
14 
15 Process finished with exit code 0 
 
O valor impresso ao final do programa deveria ser 10.000.000 (10 threads X 1.000.000 de iterações), 
porém foi impresso 3.316.688. Você deve estar se perguntado por que aconteceu isso, se o GIL garante 
que apenas uma thread esteja em execução por vez. 
E por que não aconteceu isso no exemplo anterior? 
Vamos começar pelo exemplo anterior. O método utilizado para inserir um elemento na lista (append), na visão 
do GIL, é atômico, ou seja, ele é executado de forma segura e não pode ser interrompido no meio de sua execução. 
O incremento de variável (+=1), que está sendo usando no exemplo atual (linha 10), não é atômico. 
Ele é, na verdade, composto por duas operações, a leitura e a atribuição, e não temos como garantir que as 
duas operações serão realizadas atomicamente. 
Veja a figura 1, em que temos um contador inicialmente com o valor 0 e três threads incrementando 
esse contador. Para incrementar, a thread realiza duas operações: lê o valor do contador e depois atribui o 
valor lido incrementado de um ao contador. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 141 
 
 
Fonte: Estácio de Sá 
Cada thread é executada em um determinado tempo t. Em t1, a thread1 lê e incrementa o contador, 
que passa a valer 1. Em t2, a thread2 lêo contador (valor 1). Em t3, a thread3 lê e incrementa o contador, 
que passa a valer 2. Em t4, a thread2 incrementa o contador, porém a partir do valor que ela leu, que era 1. 
No final, o contador passa a valer 2, erroneamente. Esse resultado inesperado devido à sincronia na 
concorrência de threads (ou processos) se chama condição de corrida. 
Para evitar a condição de corrida, utilizamos a primitiva lock (trava). Um objeto desse tipo tem 
somente dois estados: travado e destravado. Quando criado, ele fica no estado destravado. Esse objeto tem 
dois métodos: acquire e release. 
Quando no estado destravado, o acquire muda o estado dele para travado e retorna imediatamente. 
Quando no estado travado, o acquire bloqueia a execução até que outra thread faça uma chamada ao 
método release e destrave o objeto. Veja como adaptamos o código anterior para utilizar o lock no Codigo 
13. 
Codigo 13 - Script threads_inc_lock.py 
01 from threading import Thread, Lock 
02 from multiprocessing import Process 
03 import time 
04 
05 contador = 0 
06 lock = Lock() 
07 print_lock = Lock() 
08 
09 def funcao_a(indice): 
10 global contador 
11 for i in range(1000000): 
12 lock.acquire() 
13 contador += 1 
14 lock.release() 
15 print_lock.acquire() 
16 print("Termino thread ", indice) 
17 print_lock.release() 
18 
19 if __name__ == '__main__': 
20 tarefas = [] 
21 for indice in range(10): 
22 tarefa = Thread(target=funcao_a, args=(indice,)) 
23 tarefas.append(tarefa) 
24 tarefa.start() 
25 
26 print("Antes de aguardar o termino!", contador) 
27 
28 for tarefa in tarefas: 
29 tarefa.join() 
30 
31 print("Após aguardar o termino!", contador) 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 142 
 
 
Fonte: Estácio de Sá 
Codigo 13 - Saída do script threads_inc_lock 
01 C:\Users\ftoli\PycharmProjects\estacio 
02 Antes de aguardar o termino! 73844 
03 Termino thread 1 
04 Termino thread 7 
05 Termino thread 8 
06 Termino thread 9 
07 Termino thread 2 
08 Termino thread 3 
09 Termino thread 0 
10 Termino thread 4 
11 Termino thread 6 
12 Termino thread 5 
13 Após aguardar o termino! 10000000 
14 
15 Process finished with exit code 0 
Aproveitamos este exemplo para corrigir o problema de impressão no console de forma desordenada. 
Esse problema ocorria, pois o print também não é uma operação atômica. Para resolver, envolvemos o print 
da linha 16 com outra trava, print_lock, criada na linha 7. 
Compartilhando variáveis entre processos 
Para criar uma área de memória compartilhada e permitir que diferentes processos acessem a 
mesma variável, podemos utilizar a classe value do módulo multiprocessing. 
No exemplo do Codigo 14 a seguir, vamos criar uma variável do tipo inteiro e compartilhá-la entre os 
processos. Essa variável fará o papel de um contador e a função paralelizada vai incrementá-la. 
Codigo 14 - Script processos.py 
01 from threading import Thread 
02 from multiprocessing import Process, Value 
03 
04 def funcao_a(indice, cont): 
05 for i in range(100000): 
06 with cont.get_lock(): 
07 cont.value += 1 
08 print("Termino processo ", indice) 
09 
10 if __name__ == '__main__': 
11 contador = Value('i', 0) 
12 tarefas = [] 
13 for indice in range(10): 
14 tarefa = Process(target=funcao_a, args=(indice, contador)) 
15 tarefas.append(tarefa) 
16 tarefa.start() 
17 
18 print("Antes de aguardar o termino!", contador.value) 
19 
20 for tarefa in tarefas: 
21 tarefa.join() 
22 
23 print("Após aguardar o termino!", contador.value) 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 143 
 
Codigo 14 - Saída do script processos 
01 C:\Users\ftoli\PycharmProjects\estacio_e 
02 Antes de aguardar o termino! 0 
03 Termino processo 2 
04 Termino processo 1 
05 Termino processo 0 
06 Termino processo 3 
07 Termino processo 4 
08 Termino processo 5 
09 Termino processo Termino processo 7 
10 6 
11 Termino processo 8 
12 Termino processo 9 
13 Após aguardar o termino! 1000000 
14 
15 Process finished with exit code 0 
 
Para permitir que a variável seja compartilhada, declaramos uma variável chamada contador 
utilizando o construtor da classe value, onde passamos como primeiro argumento um caractere com o tipo 
da variável compartilhada (‘i’ 🡪 inteiro) e seu valor inicial (0) (linha 11). 
Como não temos acesso a variáveis globais entre os processos, precisamos passar esta para o 
construtor process por meio do parâmetro args. Como a passagem de parâmetros é posicional, o 
parâmetro indice da funcao_a recebe o valor da variável índice e o parâmetro cont recebe uma 
referência para a variável contador (linha 14). 
Isso já é o suficiente para termos acesso a variável contador por meio do parâmetro cont da função 
funcao_a. Porém, não resolve a condição de corrida. 
Para evitar esse problema, vamos utilizar uma trava (lock) para realizar a operação de incremento, 
assim como fizemos no exemplo anterior. 
Você sabia? 
O Python já disponibiliza essa trava nos objetos do tipo value, não sendo necessário criar uma variável 
específica para a trava (lock). Observe como foi realizada a trava utilizando o método get_lock() (linha 6). 
Observe pelo console que agora nossa variável está com o valor certo: um milhão! 
Para corrigir o problema da impressão desordenada, basta criar uma variável do tipo lock e passá-la 
como parâmetro, assim como fizemos no exemplo anterior e com a variável contador. 
Verificando o aprendizado 
1. Observe as afirmativas e responda: 
I – É possível alcançar a concorrência em processadores de apenas um núcleo. 
II – O paralelismo é uma técnica para permitir executar várias operações ao mesmo tempo. 
III – Programas e processos têm a mesma definição. 
IV – As threads pertencem a um determinado processo. 
Das afirmativas anteriores, quais estão corretas? 
A. II e III. 
B. I e IV. 
C. I, II e IV. 
D. I, II. 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 144 
 
2. Qual o valor impresso pelo script a seguir:? 
Codigo 14 - Script processos.py 
minha_lista = [] 
 def adiciona(): 
for i in range(100): 
minha_lista.append(1) 
 
if __name__ == '__main__': 
tarefas = [] 
 
for indice in range(10): 
t = Thread(target=adiciona) 
tarefas.append(t) 
t.start() 
 
for indice in range(10): 
p = Thread(target=adiciona) 
tarefas.append(t) 
p.start() 
 
for tarefa in tarefas: 
tarefa.join() 
 
print(len(minha_lista)) 
A. 100. 
B. 1000. 
C. 2000. 
D. 10000. 
Apenas a thread consegue acessar a variável global minha_lista. São executadas 10 threads X 100 iterações 
= 1000. 
Python como ferramenta para desenvolvimento web 
Introdução 
Atualmente, existem diversas opções de linguagem de programação para desenvolver aplicações 
web, sendo as principais: PHP, ASP.NET, Ruby e Java. 
De acordo com o site de pesquisas W3Techs, o PHP é a linguagem mais utilizada nos servidores, 
com um total de 79% de todos os servidores utilizando essa linguagem. 
Grande parte da utilização do PHP se deve aos gerenciadores de conteúdo, como WordPress, 
Joomla e Drupal, escritos em PHP e que tem muita representatividade na web hoje. 
Você sabia? 
O Python também pode ser utilizado para desenvolver aplicações web? 
Atualmente existem diversos frameworks que facilitam a criação de aplicações web em Python. 
Os frameworks podem ser divididos em, basicamente, dois tipos: full-stack e não full-stack. 
Frameworks Full-Stack 
Os frameworks full-stack disponibilizam diversos recursos internamente, sem a necessidade de 
bibliotecas externas. Dentre os recursos, podemos citar: 
• Respostas à requisição; 
• Mecanismos de armazenamento (acesso a banco de dados); 
• Suporte a modelos (templates); 
• Manipulação de formulários; 
• Autenticação; 
• Testes; 
• Servidor para desenvolvimento, entre outros. 
O principal framework Pythonfull-stack é o Django. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 145 
 
Frameworks não Full-Stack 
Estes oferecem os recursos básicos para uma aplicação web, como resposta a requisição e suporte 
a modelos. Os principais frameworks dessa categoria são o Flask e o CherryPy. 
Normalmente, para aplicações maiores, são utilizados os frameworks full-stack, que também são um 
pouco mais complexos de se utilizar. 
Para este módulo, usaremos o Flask. 
Conceitos 
O Flask é um micro framework web em Python. 
Pela descrição de seus desenvolvedores, micro não quer dizer que toda a aplicação precisa ficar em 
apenas um arquivo ou que falta alguma funcionalidade, mas que o núcleo de funcionalidades dele é limpo 
e simples, porém extensível. 
O desenvolvedor fica livre para escolher qual suporte a modelos (templates) utilizar, qual biblioteca 
de acesso ao banco de dados e como lidar com formulários. Existem inúmeras extensões compatíveis com 
o Flask. 
Iniciar o desenvolvimento com Flask é muito simples e mostraremos isso ao longo deste módulo. 
Apesar de não ser full-stack, o Flask disponibiliza um servidor web interno para desenvolvimento. 
A configuração padrão inicia um servidor local na porta 5000, que pode ser acessado por: 
http://127.0.0.1:5000. 
Iremos começar com uma aplicação web básica que retorna “Olá, mundo.” quando acessamos pelo 
navegador o nosso servidor em http://127.0.0.1:5000. 
O nome do nosso script é flask1.py e está apresentado no Codigo 15 a seguir. 
Codigo 15 - Script flask1.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def ola_mundo(): 
07 return "Olá, mundo." 
08 
09 if __name__ == '__main__': 
10 app.run() 
 
Codigo 15 - Saída do script flask1 
1 C:\Users\ftoli\PycharmProjects\estacio_ead\venv\Scripts\phyton.exe C:/Users/ftoli/Py 
2 * Serving Flask app "principal" (lazy loading) 
3 * Enviroment: production 
4 WARNING: This is a development server. Do not use it in a production deployment. 
5 Use a production WSGI server instead. 
6 * Debug mode: off 
7 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) 
 
Na primeira linha, importamos a classe flask, que é a classe principal do framework. É a partir de 
uma instância dessa classe que criaremos nossa aplicação web. Na linha 2, é criada uma instância da classe 
flask, onde passamos __name__ como argumento para que o Flask consiga localizar, na aplicação, arquivos 
estáticos, como css e javascript, e arquivos de modelos (templates), se for o caso. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 146 
 
Você sabia? 
O Flask utiliza o conceito de rotas para direcionar o acesso às páginas (ou endpoints). As rotas servem para 
guiar as requisições feitas ao servidor para o trecho de código que deve ser executado. Os nomes das rotas são os 
nomes utilizados pelo usuário para navegar na sua aplicação. 
Por isso, utilize nomes com significado e de fácil memorização. No caso do Flask, as rotas são direcionadas 
para funções, que devem retornar algum conteúdo. 
Na linha 5, utilizamos o decorador @app.route(‘/’) para criar uma rota para a URL raiz da nossa 
aplicação (‘/’). Esse decorador espera como parâmetro a rota, ou URL, que será utilizada no navegador, por 
exemplo. 
Toda requisição feita para uma rota é encaminhada para a função imediatamente abaixo do 
decorador. No nosso caso, para a função ola_mundo (linha 6). O retorno dessa função é a resposta que o 
nosso servidor enviará ao usuário. Pela linha 7, a função ola_mundo retorna a string “Olá, mundo.”. 
Ao iniciar a execução do script, recebemos no console algumas informações, incluindo em qual 
endereço o servidor está “escutando”, observe à direita do Codigo 16. 
Ao digitar no navegador a URL http://127.0.0.1:5000, será exibida a frase “Olá, mundo.”, como na 
imagem da figura 2. 
 
Figura 2 - Resultado do acesso a http://127.0.0.1:5000. 
Aprimorando rotas 
Para ilustrar melhor o uso de rotas, vamos alterar o exemplo anterior de forma que a rota (URL) para 
a função ola_mundo seja http://127.0.0.1:5000/ola. 
Observe o Codigo 16 e compare com a anterior. Veja que o parâmetro do decorador @app.route da 
linha 5 agora é ‘/ola’. 
Codigo 16 - Script flask2.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/ola') 
06 def ola_mundo(): 
07 return "Olá, mundo." 
08 
09 if __name__ == '__main__': 
10 app.run() 
 
Se acessarmos no navegador http://127.0.0.1:5000/ola, recebemos como resposta “Olá, mundo.” 
(figura 3 A), porém, ao acessar http://127.0.0.1:5000, recebemos um erro (404) de página não encontrada 
(Not Found), pois a rota para a URL raiz da aplicação não existe mais (figura 3 B). 
http://127.0.0.1:5000/
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 147 
 
 
Figura 3 A - Resultado do acesso a http://127.0.0.1:5000/ola. Figura 3 B - Resultado do acesso a http://127.0.0.1:5000. 
Vamos acertar nossa aplicação para criar, também, uma rota para a URL raiz da aplicação 
(@app.route(‘/’)). 
Vamos chamar a função dessa rota de index e criar essa rota conforme linhas 5 a 7. Veja o resultado 
no Codigo 17 a seguir. 
Codigo 17 - Script flask3.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def index(): 
07 return "Página principal." 
08 
09 @app.route('/ola') 
10 def ola_mundo(): 
11 return "Olá, mundo." 
12 
13 if __name__ == '__main__': 
14 app.run() 
Veja, na imagem a seguir, que agora podemos acessar tanto a rota para função índice (URL: /) (figura 
4 A), onde é retornado “Página principal”, quanto a rota da função ola_mundo (URL: /ola) ( figura 4 B), que 
é retornado “Olá, mundo.”. 
 
Figura 4 A - Resultado do acesso a http://127.0.0.1:5000. Figura 4 B - Resultado do acesso a http://127.0.0.1:5000/ola. 
Recebendo parâmetros 
O decorador de rota (route) também permite que sejam passados parâmetros para as funções. Para 
isso, devemos colocar o nome do parâmetro da função entre < e> na URL da rota. 
No exemplo do Codigo 18 a seguir, vamos mudar a rota da função ola_mundo de forma que seja 
possível capturar e retornar o nome passado como parâmetro. 
 
http://127.0.0.1:5000/
http://127.0.0.1:5000/ola
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 148 
 
Codigo 18 - Script flask4.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def index(): 
07 return "Página principal." 
08 
09 @app.route('/ola/<nome>') 
10 def ola_mundo(nome): 
11 return "Olá, " + nome 
12 
13 if __name__ == '__main__': 
14 app.run() 
 
Observe a URL da rota na linha 9, em que utilizamos a variável nome entre < e>, que é o mesmo 
nome do parâmetro da função ola_mundo. Isso indica que qualquer valor que for adicionado à URL após 
‘/ola/’ será passado como argumento para a variável nome da função ola_mundo. 
Veja na figura 5 a seguir, em que acessamos a URL http://127.0.0.1:5000/ola/Amigo. 
 
Figura 5 - Resultado do acesso a http://127.0.0.1:5000/ola/Amigo. 
Porém, se tentarmos acessar a URL http://127.0.0.1:5000/ola, receberemos um erro, pois 
removemos a rota para essa URL. Para corrigir esse problema, vamos adicionar uma segunda rota para a 
mesma função, bastando adicionar outro decorador @app.route para a mesma função ola_mundo, conforme 
Codigo 19 a seguir. 
Codigo 19 - Script flask5.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def index(): 
07 return "Página principal." 
08 
09 @app.route('/ola/') 
10 @app.route('/ola/<nome>') 
11 def ola_mundo(nome="mundo"): 
12 return "Olá, " + nome 
13 
14 if __name__ == '__main__': 
15 app.run() 
 
Observe que agora temos duas rotas para a mesma função (linha 9 e 10). Em qualquer uma das 
URL, o usuário será direcionado para a função ola_mundo.Atenção 
OBS: A rota com URL ‘/ola/’ aceita requisições tanto para ‘/ola’ quanto ‘/ola/’. 
Como nessa nova configuração, o parâmetro nome pode ser vazio quando acessado pela URL ‘/ola’, 
definimos o valor padrão “mundo” para ele (linha 11). 
Ao acessar essas duas URLs ‘/ola/’ e ‘/ola/Amigo’, obtemos os resultados exibidos nos resultados 
exibidos na figura 6 A e 6 B, respectivamente. 
http://127.0.0.1:5000/ola/Amigo
http://127.0.0.1:5000/ola/Amigo
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 149 
 
 
Figura 6 A - Resultado do acesso a http://127.0.0.1:5000/ola/. Figura 6 B - Resultado do acesso a http://127.0.0.1:5000/ola/Amigo. 
Métodos HTTP 
As aplicações web disponibilizam diversos métodos para acessar uma URL: GET, POST, PUT e 
DELETE. Por padrão, as rotas do Flask somente respondem às requisições GET. Para responder 
a outros métodos, é necessário explicitar, na rota, quais métodos serão aceitos. 
Para isso, precisamos utilizar o parâmetro methods do decorador @app.route(), que espera uma lista 
de strings com o nome dos métodos aceitos. 
Observe no Codigo 20, a seguir, em que criamos a rota para a função logar e passamos como 
argumento uma lista contendo duas strings, ‘GET’ e ‘POST’ (linha 15). Isso indica que essa rota deve 
responder às requisições do tipo GET e POST. 
Codigo 20 - Script flask6.py 
01 from flask import Flask 
02 
03 app = Flask(__name__) 
04 app.debug = True 
05 
06 @app.route('/') 
07 def index(): 
08 return "Página principal." 
09 
10 @app.route('/ola/') 
11 @app.route('/ola/<nome>') 
12 def ola_mundo(nome): 
13 return "Olá, " + nome 
14 
15 @app.route('/logar', methods=['GET', 'POST']) 
16 def logar(): 
17 if request.method == 'POST': 
18 return "Recebeu post! Fazer login!" 
19 else: 
20 return "Recebeu get! Exibir FORM de login." 
21 
22 if __name__ == '__main__': 
23 app.run() 
 
Para verificar o método que foi utilizado na requisição, usamos o atributo method do objeto request, 
que retorna uma das strings: GET, POST, PUT ou DELETE. 
O objeto request é uma variável global disponibilizada pelo Flask e pode ser utilizada em todas as 
funções. Para cada requisição, um novo objeto request é criado e disponibilizado. 
Com o objeto request, temos acesso a muitas outras propriedades da requisição, como: cookie, 
parâmetros, dados de formulário, mimetype etc. 
Neste exemplo, utilizamos o atributo method do objeto request para verificar o método passado na 
requisição e retornar conteúdos diferentes dependendo do método (linhas 17 a 20). 
 
http://127.0.0.1:5000/ola/Amigo
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 150 
 
Atenção 
Caso seja requisitada uma rota que exista, porém o método não seja aceito pela rota, o erro retornado é o 405 
- Method Not Allowed (método não permitido), e não o 404 – Not Found (não encontrado), como ocorre quando a rota 
não existe. 
Observe que ativamos o modo debug do servidor interno do Flask (linha 5). Isso nos permite 
visualizar melhor os avisos e erros durante o desenvolvimento. 
Utilizando modelos 
As funções no Flask precisam retornar algo. O retorno das funções pode ser uma string simples e 
até uma string contendo uma página inteira em HTML. Porém, criar páginas dessa maneira é muito 
complicado, principalmente devido à necessidade de escapar (scape) o HTML, para evitar problemas de 
segurança, por exemplo. 
Para resolver esse problema, o Flask, por meio da extensão Jinja2, permite utilizar modelos 
(templates) que são arquivos texto com alguns recursos a mais, inclusive escape automático. 
No caso de aplicações web, os modelos normalmente são páginas HTML, que são pré-processadas 
antes de retornarem ao requisitante, abrindo um novo leque de possibilidades no desenvolvimento web. 
A cada requisição, podemos alterar uma mesma página de acordo com um contexto (valores de 
variáveis, por exemplo). Com a utilização de marcadores (tags) especiais, é possível injetar valores de 
variáveis no corpo do HTML, criar laços (for), condicionantes (if/else), filtros etc. 
1. Para criar e utilizar os modelos, por convenção, os HTMLs precisam ficar dentro da pasta 
templates, no mesmo nível do arquivo que contém a aplicação Flask. 
2. Para ilustrar, no próximo exemplo (Codigo 21), vamos alterar nossa aplicação de forma que 
seja retornada uma página HTML ao se acessar a raiz da aplicação (‘/’). 
3. Para isso, vamos criar um arquivo chamado indice.html na pasta templates, no mesmo nível 
do script flask7.py, conforme vemos na árvore de diretório abaixo. 
 
O conteúdo do modelo indice.html está exibido abaixo do Codigo 21 
4. Para o modelo ser acessado na URL raiz (‘/’), a função index() deve ser a responsável por 
retorná-lo. Para isso, vamos utilizar a função render_template disponibilizada pelo Flask, 
que recebe o nome do arquivo que desejamos retornar. 
Observe a linha 7 do script flask7.py, em que utilizamos essa função e passamos “indice.html” como 
parâmetro. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 151 
 
Codigo 21 - Script flask7.py 
01 from flask import Flask, render_template 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def index(): 
07 return render_template('indice.html') 
08 
09 @app.route('/ola/') 
10 @app.route('/ola/<nome>') 
11 def ola_mundo(nome="mundo"): 
12 return "Olá, " + nome 
13 
14 if __name__ == '__main__': 
15 app.run() 
 
Codigo 21 - Modelo indice.html 
1 <!DOCTYPE html> 
2 <html> 
3 <body> 
4 <h1>Página principal!</h1> 
5 <h2>Usando templates</h2> 
6 </body> 
7</html> 
Ao acessar http://127.0.0.1:5000, recebemos o resultado exibido na figura 7. 
 
Figura 7 - Resultado do acesso a http://127.0.0.1:5000. 
Como dito anteriormente, os modelos são páginas HTML turbinadas, nas quais podemos utilizar 
delimitadores especiais para alterar nossa página. Os dois tipos de delimitadores são: 
Expressões: {{ ... }} 
Que serve para escrever algo no modelo, como o valor de uma variável. 
Declarações: {% ... %} 
Utilizado em laços e condicionantes, por exemplo. 
Antes de serem retornadas ao usuário, essas páginas são renderizadas, ou seja, os delimitadores 
são computados e substituídos. 
No próximo exemplo, Código 22, vamos alterar a nossa aplicação de forma que o nome passado 
como parâmetro para a rota ‘/ola/<nome>’ seja exibido dentro do HTML. 
Para isso, vamos criar um arquivo chamado ola.html na pasta templates, conforme abaixo no Codigo 
22. Observe que utilizamos o delimitador de expressões com a variável ({{nome_recebido}}), indicando que 
vamos escrever o conteúdo dessa variável nesse local após a renderização (linha 4 do arquivo ola.html). 
 
http://127.0.0.1:5000/
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 152 
 
Codigo 22 - Script flask8.py 
01 from flask import Flask, render_template 
02 
03 app = Flask(__name__) 
04 
05 @app.route('/') 
06 def index(): 
07 return render_template('indice.html') 
08 
09 @app.route('/ola/') 
10 @app.route('/ola/<nome>') 
11 def ola_mundo(nome="mundo"): 
12 return "Olá, ", nome_recebido = nome 
13 
14 if __name__ == '__main__': 
15 app.run() 
 
Codigo 22 - Modelo ola.html 
1<!DOCTYPE html> 
2<html> 
3 <body> 
4 <h1>Olá, {{ nome_recebido }}</h1> 
5 </body> 
6</html> 
 
Além de informar a página que queremos renderizar na função render_templates, podemos passar 
uma ou mais variáveis para essa função. Essas variáveis ficarão disponíveis para serem utilizadas em 
expressões ({{ }}) e declarações ({% %}) dentro do modelo (template). 
No exemplo, desejamos exibir o nome passado via URL na página. Para passar a variável nome para 
o HTML, precisamos chamar a função render_template com um parâmetro a mais, conforme linha 12 e 
destacado a seguir (figura 8). 
 
Figura 8 - Destaque da sintaxe da função render_template do Flask. Fonte: Estácio de SáA variável nome_recebido estará disponível para ser usada dentro do modelo ola.html. Esse nome 
pode ser qualquer outro escolhido pelo programador, mas lembre-se de que ele será usado, também, dentro 
do modelo. 
Para finalizar, utilizamos o delimitador de expressões envolvendo o nome da variável (linha 4 do 
html). Ao ser renderizada, essa expressão será substituída pelo valor da variável, conforme figura 9 a seguir, 
onde passamos a string “Amigo” para a variável nome e, consequentemente, nome_recebido. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 153 
 
 
Figura 9 - Resultado do acesso a http://127.0.0.1:5000/ola/Amigo. 
Verificando o aprendizado 
1. Considere o código a seguir, em que temos um servidor Flask escutando na porta 5000, e responda: 
exercicio1.py 
from flask import Flask 
app = Flask(__name__) 
@app.route('/ola') 
def ola_mundo(): 
return "Olá, mundo" 
 
@app.route('/ola') 
def ola_mundo(nome="mundo"): 
return "Olá, " + nome 
 
if __name__ == '__main__': 
app.run() 
O que será apresentado no navegador se acessarmos a URL http://127.0.0.1:5000/ola/EAD? 
A. Olá, mundo. 
B. Olá, mundo. 
Olá, EAD. 
C. Olá, EAD. 
D. O programa vai apresentar um erro. 
 
A URL acessada está de acordo com a rota da linha 9. 
2. Considere o código a seguir, no qual temos um servidor Flask escutando na porta 5000, e responda: 
exercicio2.py 
from flask import Flask 
app = Flask(__name__) 
 
@app.route('/ola', methods=['POST']) 
def ola_post(): 
return "Olá, GET" 
 
@app.route('/ola') 
def ola_get(nome="mundo"): 
return "Olá, POST" 
 
if __name__ == '__main__': 
app.run() 
 
O que será apresentado no navegador se acessarmos a URL http://127.0.0.1:5000/ola? 
A. Olá, GET. 
B. Olá, GET. 
Olá, POST. 
C. Olá, POST. 
D. O programa vai apresentar um erro. 
 
O navegador utiliza, por default, o método GET. Com isso, será executada a rota para a função ola_get, da 
linha 10. 
http://127.0.0.1:5000/ola/Amigo
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 154 
 
Python como ferramenta para ciência de dados 
Introdução 
Desde o século XVII, as ciências experimentais e teóricas são reconhecidas pelos cientistas como 
os paradigmas básicos de pesquisa para entender a natureza. De umas décadas para cá, a simulação 
computacional de fenômenos complexos evoluiu, criando o terceiro paradigma, a ciência computacional. 
A ciência computacional fornece ferramentas necessárias para tornar possível a exploração de 
domínios inacessíveis à teoria ou experimento. 
Com o aumento das simulações e experimentos, mais dados são gerados e um quarto paradigma 
emerge, que são as tecnologias e técnicas associadas à ciência de dados. 
A ciência de dados é uma área de conhecimento que envolve a utilização de dados para gerar 
impactos em uma instituição, seja uma universidade, uma empresa, um órgão federal etc., de forma a 
resolver um problema real utilizando os dados. 
Em 1996, Fayyad (1996) apresentou a definição clássica do processo de descoberta de 
conhecimento em bases de dados, conhecido por KDD (Knowledge Discovery in Databases): 
“KDD é um processo, de várias etapas, não trivial, interativo e iterativo, para identificação de 
padrões compreensíveis, válidos, novos e potencialmente úteis a partir de grandes conjuntos de 
dados”. 
As técnicas de KDD (FAYYAD, 1996), também conhecidas como mineração de dados, normalmente 
se referem à extração de informações implícitas, porém úteis, de uma base de dados. 
Essas aplicações, tipicamente, envolvem o uso de mineração de dados para descobrir um novo 
modelo, e então os analistas utilizam esse modelo em suas aplicações. 
O processo de KDD é basicamente composto por três grandes etapas: pré-processamento, 
mineração de dados e pós-processamento. 
A figura 10, a seguir, mostra todo o processo de KDD. 
 
Figura 10 - Visão geral dos passos que compõe o processo de KDD. Fonte: Estácio de Sá 
A primeira etapa do processo de KDD, conhecida como pré-processamento, é responsável por 
selecionar, preparar e transformar os dados que serão utilizados pelos algoritmos de mineração. 
Algumas atividades envolvidas no reprocessamento são: 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 155 
 
Coleta e integração: 
Quando é necessário que dados provenientes de diversas fontes sejam consolidados em uma única 
base de dados. Esta atividade é bastante encontrada na construção de data warehouses; 
Codificação: 
Significa transformar a natureza dos valores de um atributo. Isto pode acontecer de duas diferentes 
formas: uma transformação de dados numéricos em categóricos — codificação numérico-
categórica, ou o inverso — codificação categórico-numérica; 
Construção de atributos: 
Após a coleta e integração dos dados, pode ser necessário criar colunas em uma tabela, por 
exemplo, refletindo alguma transformação dos dados existentes em outras colunas; 
Limpeza dos dados: 
Pode ser subdividida em complementação de dados ausentes, detecção de ruídos, e eliminação 
de dados inconsistentes; 
A partição dos dados: 
Consiste em separar os dados em dois conjuntos disjuntos. Um para treinamento (abstração do 
modelo de conhecimento) e outro para testes (avaliação do modelo gerado). 
A segunda etapa do KDD, conhecida como mineração de dados, é a aplicação de um algoritmo 
específico para extrair padrões de dados. Hand (2001) define a etapa de mineração de dados da seguinte 
forma: 
“Mineração de Dados é a análise de (quase sempre grandes) conjuntos de dados observados para 
descobrir relações escondidas e para consolidar os dados de uma forma tal que eles sejam 
inteligíveis e úteis aos seus donos.” 
Esta etapa, normalmente, é a que atrai maior atenção, por ser ela que revela os padrões ocultos nos 
dados. 
Os algoritmos de mineração podem ser classificados como supervisionados e não supervisionados. 
Nos primeiros, os algoritmos “aprendem” baseados nos valores que cada dado já possui. Os 
algoritmos são treinados (ajustados), aplicando uma função e comparando o resultado com os 
valores existentes. 
Já nos não supervisionados, os dados não foram classificados previamente e os algoritmos tentam 
extrair algum padrão por si só. 
A seguir, serão apresentados alguns algoritmos que podem ser realizados durante a etapa de 
mineração de dados. 
1. Não supervisionados: 
A. Regras de associação 
• Uma das técnicas de mineração de dados mais utilizada para comércio eletrônico, cujo 
objetivo é encontrar regras para produtos comprados em uma mesma transação. Ou 
seja, a presença de um produto em um conjunto implica a presença de outros produtos 
de outro conjunto; com isso, sites de compras nos enviam sugestões de compras 
adicionais, baseado no que estamos comprando. 
B. Agrupamento 
• Reúne, em um mesmo grupo, objetos de uma coleção que mantenham algum grau de 
afinidade. É utilizada uma função para maximizar a similaridade de objetos do mesmo 
grupo e minimizar entre elementos de outros grupos. 
2. Supervisionados: 
A. Classificação 
• Tem como objetivo descobrir uma função capaz de mapear (classificar) um item em uma 
das várias classes predefinidas. Se conseguirmos obter a função que realiza esse 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 156 
 
mapeamento, qualquer nova ocorrência pode ser também mapeada, sem a necessidade 
de conhecimento prévio da sua classe; 
B. Regressão linear 
• É uma técnica para se estimar uma variável a partir de uma função. A regressão, 
normalmente, tem o objetivo de encontrar um valor que não foi computado inicialmente. 
A última etapa do KDD, o pós-processamento, tem como objetivo transformar os padrões dos dados 
obtidos na etapa anterior, de forma a torná-los inteligíveis, tanto ao analista de dados quanto ao especialista 
do domínio da aplicação (SOARES, 2007). 
Conceitos 
Vamos apresentar algumas situaçõesde forma a explicar alguns algoritmos de mineração e como 
eles podem ser implementados em Python. 
Utilizaremos a biblioteca Pandas para realizar a leitura de dados, a biblioteca Scikit-Learn para 
realizar o treinamento e utilização dos algoritmos de mineração de dados e a biblioteca matplotlib para gerar 
a visualização de resultados. 
Supervisionado – regressão linear 
Neste exemplo, vamos utilizar uma série histórica fictícia de casos de dengue de uma determinada 
cidade e, com o auxílio do algoritmo supervisionado de regressão linear, predizer casos futuros. 
A série está em uma planilha (arquivo CSV) com duas colunas, ano e casos (número de casos). Na 
planilha, temos o número de casos de 2001 a 2017. Vamos utilizar essa série histórica e aplicar o algoritmo 
de regressão linear para estimar os casos de dengue para o ano de 2018. 
No Codigo 23, a seguir, temos o código do script regressao.py, o arquivo CSV (dados_dengue.csv) 
e a saída do console. 
 
Codigo 23 - Script regressao.py 
01 import matplotlib.pyplot as plt 
02 from sklearn.linear_model import LinearRegression 
03 import pandas 
04 
05 ############# Pré-processamento ############### 
06 # Coleta e Integração 
07 arquivo = pandas.read_csv('dados_dengue.csv') 
08 
09 anos = arquivo[['ano']] 
10 casos = arquivo[['casos']] 
11 
12 ############## Mineração ################# 
13 regr = LinearRegression() 
14 regr.fit(X=anos, y=casos) 
15 
16 ano_futuro = [[2018]] 
17 casos_2018 = regr.predict(ano_futuro) 
18 
19 print('Casos previstos para 2018 ->', int(casos_2018)) 
20 
21 ############ Pós-processamento ################ 
22 plt.scatter(anos, casos, color='black') 
23 plt.scatter(ano_futuro, casos_2018, color='red') 
24 plt.plot(anos, regr.predict(anos), color='blue') 
25 
26 plt.xlabel('Anos') 
27 plt.ylabel('Casos de dengue') 
28 plt.xticks([2018]) 
29 plt.yticks([int(casos_2018)]) 
30 
31 plt.show() 
 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 157 
 
Codigo 23 - Dados_dengue.csv 
01 ano,casos 
02 2017,450 
03 2016,538 
04 2015,269 
05 2014,56 
06 2013,165 
07 2012,27 
08 2011,156 
09 2010,102 
10 2009,86 
11 2008,42 
12 2007,79 
13 2006,65 
14 2005,58 
15 2004,39 
16 2003,23 
17 2002,15 
18 2001,28 
 
Codigo 23 - Saída do script regressao.py 
1 C:\Users\fotoli\PycharmProjects\estac 
2 Casos previstos para 2018 -> 330 
 
Após importar os módulos necessários, vamos passar para a primeira etapa do KDD, o pré-
processamento. Neste caso simples, vamos realizar apenas a coleta e integração que, na prática, é carregar 
a planilha dentro do programa. 
Para isso, utilizamos a função read_csv da biblioteca Pandas, passando como parâmetro o nome do 
arquivo (linha 7). 
A classe da biblioteca Scikit-Learn utilizada para realizar a regressão linear se chama 
LinearRegression. Para realizar a regressão, ela precisa dos dados de treinamento (parâmetro X) 
e seus respectivos resultados (parâmetro y). 
No nosso exemplo, como desejamos estimar o número de casos, vamos utilizar os anos como dado 
de treinamento e o número de casos como resultado. Ou seja, teremos os anos no parâmetro X e os casos 
no parâmetro y. 
Como estamos usando apenas uma variável para o parâmetro X, o ano, temos uma regressão linear 
simples e o resultado esperado é uma reta, onde temos os anos no eixo x e os casos no eixo y. 
Após carregar o arquivo, vamos separar os dados das colunas nas respectivas variáveis. Observe a 
sintaxe para obter os anos (linha 9) e casos (linha 10). O Pandas detecta, automaticamente, o nome das 
colunas e permite extrair os elementos das colunas utilizando o nome. 
Atenção 
O próximo passo é criar o objeto do tipo LinearRegression e atribuí-lo a uma variável (linha 13). Esse objeto 
será utilizado para treinar (ajustar) a equação da reta que será gerada pela regressão. Para realizar o treinamento (fit), 
precisamos passar os parâmetros X e y (linha 14). 
Após a execução do método fit, o objeto regr está pronto para ser utilizado para predizer os casos 
para os anos futuros, utilizando o método predict (linha 17). 
Ao chamar o método predict passando o ano 2018 como argumento, recebemos como retorno o 
número casos previsto para 2018, conforme impresso no console da figura 33 (330). 
A partir da linha 21, temos a etapa de pós-processamento, na qual utilizamos a biblioteca matplotlib 
para exibir um gráfico com os dados da série (pontos em preto), a reta obtida pela regressão, em azul, e o 
valor predito para o ano de 2018, em vermelho (figura 11). 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 158 
 
 
Figura 11 - Gráfico da série dos casos de dengue. Fonte: Estácio de Sá 
Supervisionado ‒ classificação 
Os algoritmos de classificação são do tipo supervisionado, nos quais passamos um conjunto de 
características sobre um determinado item de uma classe de forma que o algoritmo consiga compreender, 
utilizando apenas as características, qual a classe de um item não mapeado. 
Para este exemplo, vamos utilizar um conjunto de dados (dataset) criado em 1938 e utilizado até 
hoje: o dataset da flor de íris (Iris Dataset). Ele contém informações de cinquenta amostras de três diferentes 
classes de Flor de Íris (Iris setosa, Iris virginica e Iris versicolor). 
No total, são quatro características para cada amostra, sendo elas o comprimento e a largura, em 
centímetros, das sépalas e pétalas de rosas. 
Por ser um dataset muito utilizado e pequeno, o Scikit-Learn já o disponibiliza internamente. 
Vamos treinar dois algoritmos de classificação, árvore de decisão e máquina de vetor suporte (suport 
vector machine – SVM) para montar dois classificadores de flores de íris. A forma como são implementados 
esses algoritmos estão fora do escopo deste módulo. 
Confira o script a seguir, Codigo 24, em que utilizamos esses dois algoritmos. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 159 
 
Codigo 24 - Script classificacao.py 
01 from sklearn.datasets import load_iris, fetch_kddcup99 
02 from sklearn.metrics import accuracy_score 
03 from sklearn.model_selection import train_test_split 
04 from sklearn.tree import DecisionTreeClassifier, export_text, plot_tree 
05 from sklearn.svm import SVC 
06 
07 ################## Pré-processamento ################### 
08 # Coleta e Integração 
09 iris = load_iris() 
10 
11 caracteristicas = iris.data 
12 rotulos = iris.target 
13 
14 print("Caracteristicas:\n", caracteristicas[:2]) 
15 print("Rótulos:\n", rotulos[:2]) 
16 print('########################################################') 
17 
18 # Partição dos dados 
19 carac_treino, carac_teste, rot_treino, rot_teste = train_test_split(caracteristicas, rotulos) 
20 
21 ################### Mineração ##################### 
22 
23 ############---------- Arvore de Decisão -----------############ 
24 arvore = DecisionTreeClassifier(max_depth=2) 
25 arvore.fit(X=carac_treino, y=rot_treino) 
26 
27 rot_preditos = arvore.predict(carac_teste) 
28 acuracia_arvore = accuracy_score(rot_teste, rot_preditos) 
29 ############-------- Máquina de Vetor Suporte ------############ 
30 clf = SVC() 
31 clf.fit(X=carac_treino, y=rot_treino) 
32 
33 rot_preditos_svm = clf.predict(carac_teste) 
34 acuracia_svm = accuracy_score(rot_teste, rot_preditos_svm) 
35 
36 ################ Pós-processamento #################### 
37 print("Acurácia Árvore de Decisão:", round(acuracia_arvore, 5)) 
38 print("Acurácia SVM:", round(acuracia_svm, 5)) 
39 print('########################################################') 
40 
41 r = export_text(arvore, feature_names=iris['feature_names']) 
42 print("Estrutura da árvore") 
43 print(r) 
 
Codigo 24 - Saída do script classificacao.py 
01 C:\Users\fotoli\PycharmProjects\estacio_ead\ 
02 Caracteristicas: 
03 [[5.1 3.5 1.4 0.2] 
04 [4.9 3. 1.4 0.2]] 
05 Rótulos: 
06 [0 0]07 ########################################### 
08 Acurácia Árvore de Decisão: 0.92105 
09 Acurácia SVM: 0.97368 
10 ########################################### 
11 Estrutura da árvore 
12 |--- petal width (cm) <= 0.80 
13 | |--- class: 0 
14 |--- petal width (cm) > 0.80 
15 | |--- petal width (cm) <= 1.75 
16 | | |--- class: 1 
17 |--- petal width (cm) > 1.75 
18 | | |--- class: 2 
19 Process finished with exit code 0 
 
Etapa 01 
Na etapa de pré-processamento, vamos começar pela coleta e integração, que é a obtenção do 
dataset de flores utilizando a função load_iris() (linha 9). Esta função retorna um objeto onde 
podemos acessar as características das flores pelo atributo data e os rótulos, ou classes das flores, 
pelo atributo target. 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 160 
 
Etapa 02 
Na linha 11, separamos as características das flores na variável características. Ela contém uma 
lista com 150 itens, onde cada item contém outra lista com quatro elementos. Observe o conteúdo 
dos dois primeiros itens desta lista no console. 
Cada um dos quatro elementos corresponde ao comprimento da sépala, largura da sépala, 
comprimento da pétala e largura da pétala, respectivamente. 
Etapa 03 
Na linha 12, separamos os rótulos (ou classes) na variável rótulo. Ela contém uma lista com 150 
itens que variam entre 0, 1 ou 2. Cada número corresponde a uma classe de flor (0: Iris-Setosa; 
1:Iris-Versicolour; 2:Iris-Virginica). Como dito na introdução deste módulo, esse mapeamento entre 
categorias e números se chama codificação categórico-numérica. Essa etapa de pré-
processamento já foi realizada e disponibilizada pela função load_iris(). 
Etapa 04 
Outra etapa de pré-processamento que precisaremos realizar é a partição dos dados. Ela nos 
permitirá verificar a qualidade do algoritmo de classificação. Para isso, precisamos particionar 
nossos dados em treino e teste. 
Os dados de treino são, como o próprio nome diz, utilizados para treinar (ajustar) o algoritmo, 
enquanto os dados de testes são utilizados para verificar a acurácia dele, comparando o valor calculado 
para os testes com os valores reais. 
Dica 
Para separar as amostras em treino e teste, o Scikit-Learn disponibiliza uma função chamada train_test_split, 
que recebe como primeiro parâmetro uma lista com as características e segundo parâmetro uma lista com os rótulos. 
Essa função retorna quatro novas listas: 
• De treino; 
• De teste das características; 
• De treino; 
• De teste dos rótulos. 
Observe a linha 19, onde utilizamos essa função para gerar quatro novas variáveis: características 
para treino (carac_treino); características para teste (carac_teste); rótulos para treino (rot_treino); e rótulos 
para teste (rot_teste). 
Com a etapa de pré-processamento concluída, o próximo passo é treinar um algoritmo de 
classificação com os dados de treino. Para isso, criamos uma instância do classificador DecisionTree 
passando como parâmetro a profundidade máxima da árvore, ou seja, o número máximo de níveis, ou 
camadas, a partir do nó raiz, que a árvore encontrada poderá ter (linha 24). 
Veremos como a árvore ficou ao término do script. Esse objeto será utilizado para treinar (ajustar) 
a árvore de decisão. Para realizar o treinamento (fit), precisamos passar os parâmetros X e y, que 
conterão as características de treino e rótulos de treino respectivamente (linha 25). 
Após treinado o algoritmo, vamos utilizar o método predict do objeto árvore, passando como 
argumento as características para teste. Como resultado, receberemos uma lista com os rótulos preditos 
(linha 27). 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 161 
 
Esse resultado será utilizado como parâmetro para a função accuracy_score, que calcula a acurácia 
do classificador, comparando os resultados preditos com os resultados reais (linha 28). 
Analogamente, faremos o treinamento de um algoritmo de classificação utilizando o SVM, por meio 
da classe SVC (support vector classification) em que utilizaremos os valores padrão do construtor 
para o classificador (linha 30 a 34). 
No pós-processamento, vamos imprimir a acurácia de cada classificador (linha 37 e 38) e uma 
representação textual da árvore, utilizando a função export_text (linha 41). 
Observe que a acurácia do classificador SVC foi ligeiramente melhor que da árvore de decisão, 0,97 
contra 0,92 da árvore. 
Uma representação gráfica da árvore de decisão gerada pode ser vista na figura 12. 
 
Figura 12 - Representação da árvore de decisão com profundidade 2 
Alterando a profundidade da árvore para 3 e executando novamente o programa, encontramos uma 
acurácia de 0,97 e a seguinte árvore é exibida na figura 13: 
 
Figura 13 - Representação da árvore de decisão com profundidade 3 
Durante o treinamento de algoritmos, devemos experimentar diferentes parâmetros, a fim de 
encontrar o melhor resultado. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 162 
 
Não supervisionado ‒ agrupamento 
O objetivo de um algoritmo de agrupamento é reunir objetos de uma coleção que mantenham algum 
grau de afinidade. É utilizada uma função para maximizar a similaridade de objetos do mesmo grupo 
e minimizar entre elementos de outros grupos. 
Exemplos de algoritmo de agrupamento são k-means (k-medias) e mean-shift. 
No próximo exemplo (Codigo 25), vamos utilizar o algoritmo k-medias para gerar grupos a partir do 
dataset de flor de íris. Porém, como o agrupamento é um algoritmo não supervisionado não utilizaremos os 
rótulos para treiná-lo. O algoritmo vai automaticamente separar as amostras em grupos, que serão 
visualizados em um gráfico. 
Na etapa de pré-processamento, vamos começar pela coleta e integração que é a obtenção do 
dataset de flores utilizando a função load_iris() (linha 8). 
Na linha 10, separamos as características das flores na variável características. Lembrando que as 
características das flores são: comprimento da sépala (índice 0), largura da sépala (índice 1), comprimento 
da pétala (índice 2) e largura da pétala (índice 3). 
Na etapa de mineração de dados, vamos treinar o algoritmo de agrupamento K-medias com as 
características das flores. Para isso, criamos uma instância da classe KMeans passando como 
parâmetro o número de grupos (ou classes) que desejamos que o algoritmo identifique (n_clusters) 
(linha 13). 
Passamos o número 3, pois sabemos que são 3 classes de flor, mas poderíamos alterar esse valor. 
O objeto grupos criado será utilizado para treinar (ajustar) o algoritmo. Para realizar o treinamento (fit), 
precisamos passar apenas parâmetros X, que conterá as características das flores (linha 14). 
Após o treino, podemos utilizar o atributo labels_ do objeto grupos para retornar uma lista com o 
índice do grupo ao qual cada amostra pertence. Como o número de grupos (n_clusters) é 3, o índice varia 
entre: 0, 1 e 2. 
Codigo 25 - Script agrupamento.py 
01 import matplotlib.pyplot as plt 
02 from mpl_toolkits.mplot3d import Axes3D 
03 from sklearn.cluster import KMeans 
04 from sklearn.datasets import load_iris 
05 
06 ################## Pré-processamento ################### 
07 # Coleta e Integração 
08 iris = load_iris() 
09 
10 caracteristicas = iris.data 
11 
12 ################### Mineração ##################### 
13 grupos = KMeans(n_clusters=3) 
14 grupos.fit(X=caracteristicas) 
15 labels = grupos.labels_ # indice do grupo ao qual cada amostra pertence 
16 
17 ################ Pós-processamento #################### 
18 fig = plt.figure(1) 
19 ax = Axes3D(fig) 
20 ax.set_xlabel('Comprimento Sépala') 
21 ax.set_ylabel('Largura Sépala') 
22 ax.set_zlabel('Comprimento Pétala') 
23 ax.scatter(caracteristicas[:, 0], caracteristicas[:, 1], caracteristicas[:, 2], c=grupos.labels_, edgecolor='k') 
24 
25 target = iris.target 
26 fig = plt.figure(2)27 ax = Axes3D(fig) 
28 ax.set_xlabel('Comprimento Sépala') 
29 ax.set_ylabel('Largura Sépala') 
30 ax.set_zlabel('Comprimento Pétala') 
31 ax.scatter(caracteristicas[:, 0], caracteristicas[:, 1], caracteristicas[:, 2], c=target, edgecolor='k') 
32 
33 plt.show() 
 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 163 
 
A partir da linha 12, temos a etapa de pós-processamento, em que utilizamos a biblioteca matplotlib 
para exibir dois gráficos, onde objetos do mesmo grupo apresentam a mesma cor. 
O gráfico da figura 14 A contém os resultados do agrupamento e o gráfico figura 14 B contém os 
resultados reais da amostra. 
 
Figura 14 A - Resultado do agrupamento e Figura 14 B - Resultados reais da amostra. Fonte: Estácio de Sá 
Verificando o aprendizado 
1. De acordo com o processo de descoberta de conhecimento em base de dados (KDD) e analisando as 
assertivas a seguir, quais atividades podem fazer parte da etapa de pré-processamento? 
I. Coleta e Integração. 
II. Codificação. 
III. Construção de atributos. 
IV. Visualização dos dados. 
 
Agora, assinale a alternativa correta: 
A. I e II 
B. I, II e III 
C. I, III e IV 
D. II, III e IV 
 
Todas fazem parte do pré-processamento, exceto a visualização, que faz parte do pós-processamento. 
 
2. Em algumas situações, precisamos transformar um atributo ou característica de uma amostra de categoria 
para um número. Qual o nome dessa atividade? 
A. Coleta e integração. 
B. Codificação. 
C. Construção de atributos. 
D. Partição dos dados. 
 
A codificação categório-numérica transforma string em números. 
Considerações finais 
Como visto neste tema, a linguagem funcional pode resolver alguns problemas relacionados à 
execução do programa, chamados de efeitos colaterais. 
Apostila de Paradigmas de Linguagens de Programação em Python 
Marcio Quirino - 164 
 
Mesmo que não utilizemos todas as diretrizes da programação funcional, como imutabilidade dos 
dados, é uma boa prática utilizarmos funções puras, de forma a evitar a dependência do estado da aplicação 
e alteração de variáveis fora do escopo da função. 
Em Python, podemos criar tanto programas concorrentes quanto paralelos. Apesar do GIL (Global 
Interpreter Lock) permitir executar apenas uma thread de cada vez por processo, podemos criar múltiplos 
processos em uma mesma aplicação. 
Com isso, conseguimos tanto gerar códigos concorrentes (múltiplas threads), quanto paralelos 
(múltiplos processos). 
Apesar do Python não ser a primeira escolha para desenvolvimento web, mostramos como é simples 
a utilização do framework Flask para essa finalidade. Assim como o Flask, outros frameworks mais 
completos, como Django, facilitam o desenvolvimento desse tipo de aplicação. Sites como Instagram e 
Pinterest utilizam a combinação Python+Django, mostrando que essa combinação é altamente escalável! 
A utilização do Python como ferramenta para ciência de dados evolui a cada dia. As principais 
bibliotecas para análise e extração de conhecimento de base de dados, mineração de dados e aprendizado 
de máquinas têm uma implementação em Python. 
Apesar de não ter sido mostrado, neste tema, o console do Python é muito utilizado para realizar 
experimentações nesta área. 
Referências 
DICIONÁRIO ONLINE DE PORTUGUÊS. Definições e significados de mais de 400 mil palavras. 
Todas as palavras de A a Z. 2009-2020. 
FAYYAD, U. M.; PIATETSKY-SHAPIRO, G.; SMYTH, P.; UTHURUSAMY, R. (Eds.). From data 
mining to knowledge discovery in databases. AI Magazine, v. 17, n. 3, p. 37-54, 1996. 
FLASK. Web development, one drop at a time. 2010. 
HAND, D.; MANNILA, H.; SMYTH, P. Principles of data mining. Massachusetts: MIT Press, 1991. 
HUNT, J. A beginners guide to Python 3 programming. Basileia: Springer, 2019. 
MATPLOBIT. Visualization with Python. John Hunter, Darren Dale, Eric Firing, Michael Droettboom 
and the Matplotlib development team. 2012-2020. 
PANDAS. Sponsored project of NumFOCUS. 2015. 
PYTHON. Python Software Foundation. Copyright 2001-2020. 
SCIKIT-LEARN. Machine Learning in Python. 2007. 
W3TECHS. Web Technology Surveys. 2009-2020. 
Explore+ 
Acesse a documentação oficial do Python sobre as funções e os operadores que se integram bem 
ao paradigma de programação funcional, para aprender mais sobre o assunto. 
Pesquise no site da Jinja2 e conheça mais detalhadamente as funcionalidades da linguagem de 
modelos (templates) para Python.

Mais conteúdos dessa disciplina