Fundamentos
Variáveis e tipos de dados em Python: int, float, str e bool
O que é uma variável, como escolher nomes, o que são int, float, str, bool e None, e por que os decimais da ESP32 dão resultados diferentes dos do computador.
Por Prof. Rodrigo Faustino · Atualizado em · 13 min de leitura
Uma variável é um nome que aponta para um valor guardado na memória. O tipo diz que espécie de valor é e, por consequência, o que se pode fazer com ele. Quatro tipos cobrem quase tudo no começo: int para números inteiros, float para números com parte decimal, str para texto e bool para verdadeiro ou falso. O Python descobre o tipo olhando para o valor que você escreveu, e o mesmo nome pode apontar para tipos diferentes ao longo do programa.
Nos artigos anteriores você já usou variáveis sem muita cerimônia: preco = 3.5, nome = input(...). Aqui o assunto é fazer isso com consciência. Saber qual tipo está dentro de cada nome explica a maior parte dos resultados estranhos que aparecem nas primeiras semanas, desde a soma que dá 53 até a comparação de decimais que dá certo no computador e errado na placa, ou o contrário.
O problema: para a máquina, cinco não é só cinco
Escreva 5 num caderno e o leitor sabe o que fazer com ele. Para o computador existem pelo menos três coisas diferentes que se escrevem de maneira parecida: o número inteiro 5, o decimal 5.0 e o texto "5", um caractere que por acaso é um dígito. Cada um ocupa a memória de um jeito, responde a operações diferentes e aparece de forma diferente na tela. O tipo é o que resolve essa ambiguidade.
Uma imagem útil é a da etiqueta. Numa cozinha, o pote de açúcar tem uma etiqueta escrita "açúcar". A etiqueta não é o açúcar, é só um nome colado num conteúdo. Se você tirar a etiqueta e colar em outro pote, o nome passa a apontar para outra coisa. Numa variável, o nome é a etiqueta e o valor é o conteúdo do pote. O tipo pertence ao conteúdo: o açúcar é açúcar, qualquer que seja a etiqueta.
A IA que lembra da sua vida e mora no seu computador
- Memória de longo prazo com a fonte de cada resposta
- Funciona offline: seus dados ficam no seu PC
- Lê PDFs, slides, fotos e gravações de reunião
Plano Essencial grátis para sempre
Variáveis: criar, nomear e trocar
Criar uma variável é escrever o nome, o sinal de = e o valor. Não há palavra especial para "declarar", como em outras linguagens: a variável passa a existir na primeira linha em que recebe um valor. Foi o que a figura da memória mostrou no primeiro artigo da série.
Regras para o nome
Um nome de variável pode ter letras, dígitos e o sublinhado _, mas não pode começar com dígito, não pode ter espaço nem hífen e não pode ser uma palavra reservada da linguagem. As violações aparecem como erro de sintaxe, e a mensagem não ajuda muito:
2nota = 5 → SyntaxError: invalid syntax for integer with base 10
class = 5 → SyntaxError: invalid syntax
nome-completo = 5 → SyntaxError: can't assign to expressionNo primeiro caso, a placa leu 2nota inteiro como se fosse um número e reclamou que ele não é um inteiro válido na base 10. No último, o Python leu nome - completo como uma subtração, e uma subtração não pode receber valor. Letras maiúsculas e minúsculas são diferentes: total e Total são dois nomes. O simulador também aceitou nomes com acento, como média, mas a convenção entre programadores é evitá-los e escrever em ASCII, para que o código funcione em qualquer editor e em qualquer terminal.
A convenção do Python para nomes de variáveis é a snake_case: letras minúsculas e palavras separadas por sublinhado, como nota_final e preco_item. Constantes, valores que não mudam durante o programa, costumam ser escritas em maiúsculas (PI = 3.14159), embora o Python não impeça de alterá-las. O melhor nome é o que dispensa comentário: d não diz nada, dias_de_atraso diz tudo.
Trocar o valor e trocar o tipo
Uma variável pode receber valores novos quantas vezes quiser, inclusive de tipos diferentes. A figura mostra quatro linhas seguidas para o mesmo nome:
x = 10
print(type(x))
x = "dez"
print(type(x))
x = 10.0
print(type(x))
x = x > 5
print(x, type(x))O Python não reclama de nenhuma troca. A flexibilidade é cômoda em programas pequenos e perigosa em programas grandes, porque o erro só aparece quando o valor errado chega a uma conta. Depois destas quatro linhas, por exemplo, x + 1 dá 2 sem nenhum aviso: o True vale 1 nas contas. Uma regra prática é manter o mesmo tipo em cada variável durante o programa inteiro, a não ser que haja um bom motivo.
Duas formas de atribuir valem conhecer. Dá para dar o mesmo valor a vários nomes de uma vez, com a = b = 0, e dá para atribuir vários valores em paralelo, com a, b = 1, 2. A segunda forma permite trocar dois valores de lugar sem variável auxiliar: a, b = b, a. Funciona porque o Python calcula tudo o que está à direita antes de guardar qualquer coisa à esquerda.
Os quatro tipos básicos
type().A função type() mostra o tipo de qualquer valor, e é a primeira ferramenta quando uma conta se comporta de maneira estranha.
idade = 17
altura = 1.75
nome = "Ana"
aprovado = True
nada = None
print(type(idade), type(altura), type(nome), type(aprovado), type(nada))
print(idade, altura, nome, aprovado, nada)
int: números inteiros
O int guarda números sem parte decimal, positivos, negativos ou zero. É o tipo de contagens, idades, quantidades e posições. Em Python, um inteiro não tem um limite fixo de tamanho como em outras linguagens: 2 ** 100 calcula 1267650600228229401496703205376 sem estourar, e o único limite é a memória disponível. O simulador roda esse cálculo normalmente. Quando a conta envolver dois inteiros, o resultado é inteiro, com uma exceção que o artigo de operadores vai explicar: a divisão com / sempre devolve float, mesmo quando a conta fecha redonda (10 / 2 é 5.0).
float: números com parte decimal
O float guarda números com casas decimais, escritos com ponto: 1.75, 3.0, 0.001. Também aceita notação científica, em que 2.5e-5 significa 2,5 vezes dez elevado a menos cinco. Serve para medidas, médias, preços e qualquer grandeza contínua.
Aqui existe uma diferença entre o Python do computador e o MicroPython da ESP32 que merece atenção. O computador usa float de 64 bits, com cerca de 15 a 17 dígitos significativos. A ESP32 com MicroPython usa 32 bits, com cerca de 7. Isso muda o que aparece na tela e, em alguns casos, o resultado de uma comparação.
print(0.1 + 0.2)
print(0.1 + 0.2 == 0.3)
print(1 / 3)
print(16777216.0 + 1)
print(1e39)No simulador, essas linhas mostram 0.3, True, 0.33333334, 16777216.0 e inf. No Python do computador, as mesmas linhas mostram 0.30000000000000004, False, 0.3333333333333333, 16777217.0 e 1e+39. Os valores da coluna da ESP32 vêm do simulador, que reproduz o float de 32 bits do MicroPython. Como ainda não foram todos conferidos numa placa do laboratório, vale repetir o teste numa ESP32 de verdade e comparar.
Dois pontos são fáceis de lembrar. Primeiro, a partir de 16777216 (que é 2 elevado a 24) o float de 32 bits não consegue mais representar todos os inteiros, e 16777216.0 + 1 continua valendo 16777216.0. Segundo, o maior valor do tipo é cerca de 3,4 vezes dez elevado a 38. Passar disso vira inf, o infinito, em vez de gerar um erro.
Na prática, nenhum desses casos importa para a nota de um aluno. Importa quando o programa soma muitas vezes (um relógio, um acumulador de energia, um sensor lido por horas) ou compara decimais com ==. A solução costuma ser uma de duas: comparar com uma tolerância, abs(a - b) < 0.0001, ou trabalhar com inteiros. Para dinheiro, a segunda é a mais segura:
preco_centavos = 1999
quantidade = 3
total_centavos = preco_centavos * quantidade
print(total_centavos)
print(total_centavos // 100, total_centavos % 100)
print(f"R$ {total_centavos // 100},{total_centavos % 100:02d}")O programa guarda R$ 19,99 como 1999 centavos e só na hora de mostrar separa reais e centavos. A divisão // devolve a parte inteira do quociente e o % devolve o resto, que são os assuntos do próximo artigo da série. O :02d dentro da f-string completa com zero à esquerda para sempre haver dois dígitos de centavos.
str: texto
O str guarda texto entre aspas simples ou duplas, de uma palavra a um parágrafo, inclusive o texto vazio "". Duas operações são suficientes por enquanto: o + junta dois textos e o * repete um texto, e len("Ana") devolve o tamanho, 3. Textos e números não se misturam em contas: "5" + 5 é um erro, e "5" + "5" vale "55". O artigo sobre strings, no módulo de estruturas de dados, vai mostrar como fatiar e transformar texto.
bool: verdadeiro ou falso
O bool tem só dois valores, True e False, escritos com a primeira letra maiúscula. Escrever true em minúsculas termina em NameError: name 'true' isn't defined, porque o Python procura uma variável com esse nome. Valores bool aparecem principalmente como resultado de comparações (nota >= 6) e são o combustível das decisões, assunto do módulo 2.
O mais surpreendente é que qualquer valor pode ser tratado como bool. A função bool() converte, e a regra é a mesma em todo o Python: valores "vazios" ou nulos viram False, e todo o resto vira True.
print(bool(0), bool(1), bool(-3))
print(bool(0.0), bool(0.5))
print(bool(""), bool("a"), bool(" "), bool("False"), bool("0"))
print(bool(None))A saída mostra False True True, False True, False True True True True e False. O zero, o texto vazio e o None dão False. O texto "0", o texto "False" e até um texto com um único espaço dão True, porque são textos que não estão vazios. Também funciona ao contrário: True vale 1 e False vale 0 em qualquer conta numérica, e por isso True + True é 2.
None: a ausência de valor
O None é o valor que o Python usa para dizer "não há nada aqui". Tem tipo próprio, NoneType, e é o que uma função devolve quando não devolve nada de propósito. É comum ele aparecer por acidente, como você vai ver nos erros mais adiante.
Erros que até quem programa há anos comete
Os cenários abaixo não são de iniciante. Costumam aparecer até no código de gente experiente, quase sempre sob pressão ou cansaço, e em vários deles o erro mais caro é o que não dá mensagem nenhuma.
O nome quase igual
Uma pessoa com anos de prática escreve a linha de acumular o total e digita um nome diferente por engano:
total = 10
totl = total + 1
print(total)O programa roda sem erro e mostra 10. A linha 2 criou uma variável nova chamada totl e o total nunca foi alterado. É o erro de digitação mais difícil de achar, porque o Python não distingue um nome novo de um engano. Os editores com destaque de nomes ajudam, e o teste de mesa também: a coluna totl, que não deveria existir, aparece na tabela.
O == solto e o = dentro do if
A comparação com == e a atribuição com = são tão parecidas que quem programa em várias linguagens as troca. Escrever idade == 18 numa linha sozinha não dá erro: o Python calcula a comparação, obtém False e joga o resultado fora. A variável continua valendo 17.
idade = 17
idade == 18
print(idade)O Serial mostra 17. O erro inverso é mais barulhento: if idade = 18: termina em SyntaxError: invalid syntax, porque dentro de um if o Python espera uma comparação e não uma atribuição.
Sobrescrever uma função do Python
Nomes como str, input e vários outros já existem na linguagem como funções. Nada impede de usá-los como nome de variável, e a pessoa só descobre quando a função some:
str = "oi"
print(str)
print(str(5))O primeiro print mostra oi, e o segundo termina em TypeError: 'str' object isn't callable. O mesmo acontece com input = "teclado" seguido de input("Nome: "). A variável tapou a função. O sintoma é uma mensagem de que "um objeto não pode ser chamado", e a correção é trocar o nome da variável por algo mais específico, como texto ou entrada.
O texto "False" que vale True
Um valor lido como texto, de um teclado ou de um arquivo de configuração, chega como str. Se a pessoa depois escreve if valor: achando que "False" é falso, o programa entra no if:
valor = "False"
if valor:
print("entrou no if")O Serial mostra entrou no if, porque um texto não vazio é verdadeiro, qualquer que seja o seu conteúdo. Quando o dado vem de fora, a conversão para o tipo certo é um passo explícito, e a comparação com o texto (valor == "True") é mais honesta do que contar com bool().
A comparação de decimais que muda de placa
Alguém escreve um teste com == entre dois decimais, roda no computador e vê False, que é a resposta clássica. Na ESP32, a mesma linha mostra True. O oposto também acontece: um programa que funcionava no notebook por causa dos 64 bits deixa de funcionar na placa por causa dos 32. O hábito que protege é comparar com tolerância, nunca com ==.
O None que entrou numa conta
A função print() mostra um valor, mas não devolve nada. Guardar o resultado dela numa variável é um erro comum, e a variável fica com None:
soma = print("Calculando...")
print(soma)
soma + 1O programa mostra Calculando..., depois None, e termina em TypeError: unsupported types for __add__: 'NoneType', 'int'. A mensagem fala do tipo e não do nome, e por isso é útil lembrar que NoneType quase sempre indica uma variável que recebeu o resultado de algo que não devolvia valor.
Da ementa ao semestre planejado
- Plano de ensino e calendário montados sozinhos
- Diário de aulas pronto para colar no SIGA
- Slides e listas de exercícios com gabarito
Versão Community grátis · Windows
Exercício: a ficha do aluno
Escreva um programa que guarde o nome (texto), a idade (inteiro) e a nota (decimal) de um aluno, calcule se ele foi aprovado com nota de pelo menos 6 e mostre cada valor junto do seu tipo. Pense nas quatro variáveis antes de escrever, e preveja qual tipo cada uma terá.
nome = "Ana"
idade = 17
nota = 7.5
aprovado = nota >= 6
print(nome, type(nome))
print(idade, type(idade))
print(nota, type(nota))
print(aprovado, type(aprovado))A saída traz Ana <class 'str'>, 17 <class 'int'>, 7.5 <class 'float'> e True <class 'bool'>. A variável aprovado não recebeu True escrito à mão, ela recebeu o resultado de uma comparação, que sempre é um bool.
Para praticar a previsão, tente adivinhar o tipo destas expressões e confira com type(): 7 / 2, 7 // 2, "7", 7 > 2 e None. As respostas, nesta ordem, são float, int, str, bool e NoneType. Se errar alguma, volte à regra: a divisão com / sempre dá float, a com // entre inteiros dá int, e uma comparação sempre dá bool.
Perguntas frequentes
Preciso declarar o tipo de uma variável?
Não. O Python deduz o tipo pelo valor. Existe uma forma de anotar o tipo no código (idade: int = 17), mas ela serve como documentação e o interpretador não a usa para verificar nada.
Qual a diferença entre 5, 5.0 e "5"?
O primeiro é um int, o segundo é um float e o terceiro é um str. Na comparação, 5 == 5.0 é True porque o valor numérico é o mesmo, e 5 == "5" é False, porque um número nunca é igual a um texto.
O float da ESP32 é sempre menos preciso?
Tem menos dígitos significativos, cerca de 7, contra 15 a 17 no computador. Para medir temperatura, distância ou tensão num projeto de sala de aula, 7 dígitos sobram. A diferença pesa em contas acumuladas e em comparações exatas.
Por que o Python aceita trocar o tipo da variável?
É o que se chama de tipagem dinâmica: o tipo é verificado na hora em que a operação acontece, e não na hora de escrever. A vantagem é a rapidez para testar ideias. O preço é que erros de tipo só aparecem na execução, como o TypeError de somar texto com número.
Para continuar
A trilha Lógica com Python tem desafios que exercitam cada tipo. O Soma de dois e a Média de notas trabalham com números e conversões. O Tamanho do nome usa o len() sobre texto, e o Comparar textos devolve um bool. Em cada um, escreva primeiro o tipo que você espera para cada variável.
O próximo assunto da série são os operadores aritméticos, com a divisão inteira, o resto e a precedência das contas. Para ver os tipos trabalhando num projeto de hardware, o artigo sobre o ADC da ESP32 mostra como uma tensão vira um número que o programa precisa tratar com cuidado, e o artigo anterior da série mostra o input() entregando sempre texto.