Skip to content
This page has been auto-translated and may contain errors.View in English

Variáveis e tipos

Todo programa precisa lembrar de coisas. Um quiz precisa do nome do jogador. Um jogo precisa da pontuação atual. Um script de clima precisa da cidade que você está consultando. O Python usa variáveis para isso: nomes que você atribui a valores para poder usá-los em todo o seu programa.

Variáveis são referências nomeadas a valores. O Python vincula um nome a um objeto no lado direito do = e permite que você o revincule a qualquer momento. O tipo está no valor, não no nome.

No Python, uma variável é uma vinculação de nome: uma referência em um namespace que é resolvida para um objeto em tempo de execução. Objetos carregam tipos; nomes não. Isso é tipagem dinâmica: o mesmo nome pode referenciar objetos de tipos completamente diferentes em instruções diferentes.

python
player_name = "Ana"
score       = 0
city        = "Brasília"

Três linhas. Três coisas que o Python agora lembra. Use qualquer um desses nomes mais tarde e o Python te devolve o valor.

Cada linha cria uma vinculação: o nome à esquerda se refere ao objeto à direita. O Python avalia o lado direito primeiro, depois cria a vinculação.

Cada atribuição cria ou revincula um nome no namespace local do escopo atual. O Python avalia a expressão do lado direito completamente antes que a vinculação tenha efeito. O nome não carrega nenhuma informação de tipo por si só.

Armazenando um valor

O sinal = confunde quase todo mundo que vem da aula de matemática. No Python, = não significa "igual a". Significa armazene este valor sob este nome. Leia da esquerda para a direita:

python
city = "Brasília"

city recebe "Brasília". Você está dizendo ao Python: lembre-se de "Brasília" e rotule isso como city.

Você pode substituir o valor de uma variável a qualquer momento. O Python apenas usa o mais recente:

python
score = 0
score = 10   # score agora é 10
score = 15   # score agora é 15

= é atribuição: vincula um nome a um objeto no escopo atual. Uma abreviação padrão para atualizar uma variável é a atribuição aumentada:

python
score = 0
score += 10   # o mesmo que: score = score + 10
score *= 2    # o mesmo que: score = score * 2

Você também pode vincular vários nomes de uma vez:

python
x, y, z = 1, 2, 3
a = b = 0        # ambos começam em zero

A atribuição vincula um nome a um objeto; não copia um valor para um contêiner. Dois nomes podem referenciar o mesmo objeto:

python
a = "hello"
b = a
print(id(a) == id(b))   # True (mesmo objeto na memória)

b = "world"             # b revinculado a um novo objeto
print(id(a) == id(b))   # False
print(a)                # ainda "hello": revincular b não afetou a

id() retorna a identidade do objeto (seu endereço de memória no CPython). Essa distinção entre vinculação de nome e cópia importa mais com objetos mutáveis como listas e dicionários, abordados em capítulos posteriores.

Anotações de tipo documentam tipos esperados para ferramentas de análise estática. Elas não têm efeito em tempo de execução:

python
name:  str   = "Ana"
score: int   = 0
ratio: float = 0.85

Nomeando suas variáveis

Você escolhe o nome. O Python tem algumas regras rígidas, e a comunidade segue convenções que vale a pena adotar desde o primeiro dia. Nomes claros tornam o código legível semanas depois. Nomes enigmáticos causam dor.

O Python impõe um pequeno conjunto de regras de sintaxe para identificadores. Além disso, as convenções da PEP 8 são o padrão de fato em todo código Python e em todas as ferramentas.

As regras de sintaxe de identificadores do Python são mínimas. As convenções da PEP 8 não são impostas pelo interpretador, mas são assumidas por linters, verificadores de tipo e todo código Python profissional. Desviar delas cria atrito.

Regras que o Python impõe:

  • Apenas letras, dígitos e underscores. Sem espaços ou hifens.
  • Deve começar com uma letra ou underscore, nunca com um dígito
  • Diferencia maiúsculas de minúsculas: score, Score e SCORE são três variáveis distintas

Convenções que todo mundo segue (PEP 8):

CoisaEstiloExemplo
Variáveis e funçõessnake_caseuser_name, total_price
ConstantesUPPER_SNAKE_CASEMAX_RETRIES, BASE_URL
ClassesPascalCaseUserAccount, DataLoader
python
# nomes claros, legíveis num piscar de olhos
user_name    = "Ana"
total_price  = 49.99
is_logged_in = True
MAX_RETRIES  = 3

# você vai se arrepender desses em menos de uma hora
x   = "Ana"
tp  = 49.99
b   = True

Uma armadilha que vale a pena conhecer logo: não nomeie uma variável com o nome de uma built-in do Python como list, input, type ou print. O Python permite, mas você vai silenciosamente quebrar a built-in pelo resto daquele escopo e os erros resultantes são difíceis de rastrear.

Não sobreponha as built-ins do Python. Atribuir a list, type, input, print ou str substitui a built-in pelo resto daquele escopo sem qualquer aviso. É um bug silencioso que pode ser doloroso de encontrar.

UPPER_SNAKE_CASE é uma convenção, não algo imposto. O Python não vai te impedir de reatribuir MAX_RETRIES = 99 depois. É um sinal para outros desenvolvedores, nada mais.

Sobrepor uma built-in cria uma vinculação local que tem precedência sobre a built-in na ordem normal de busca de nomes. A built-in ainda é acessível via builtins.print e assim por diante, mas o nome sobreposto a esconde no uso normal. UPPER_SNAKE_CASE não tem imposição no nível da linguagem. Para garantias genuínas de imutabilidade que ferramentas podem verificar, typing.Final em uma anotação é a abordagem padrão.

O que você pode armazenar

O Python tem quatro tipos que você vai usar em quase todo programa. O Python descobre qual tipo você quer dizer pela forma como você escreve o valor. Você nunca declara um tipo explicitamente.

O Python infere o tipo a partir da sintaxe literal. Esses quatro tipos cobrem o espaço fundamental de valores; todo o resto na linguagem é construído sobre eles.

Os quatro tipos primitivos do Python mapeiam para objetos de runtime distintos com diferentes layouts de memória, características de precisão e semânticas de operação. O tipo é determinado pelo objeto, não pelo nome.

Texto (str)

Qualquer texto vai entre aspas, simples ou duplas. As aspas dizem ao Python que você quer caracteres literais, não um nome de variável. Uma vez criada, uma string não pode ser alterada no lugar. O capítulo Strings cobre tudo que você pode fazer com elas.

python
player_name = "Ana"
city        = "Brasília"
message     = 'Fim de jogo'

Se seu texto contém um apóstrofo, use aspas duplas para evitar ter que escapá-lo:

python
note = "It's a great day"
note = 'It\'s a great day'   # mesmo resultado, usando um escape

Strings guardam qualquer texto entre aspas simples ou duplas. Elas são imutáveis: nenhuma operação modifica uma string no lugar; toda transformação retorna uma nova. Isso importa para desempenho: usar + repetidamente dentro de um loop cria um novo objeto string a cada passo. O capítulo Strings aborda a alternativa eficiente.

python
player_name = "Ana"
city        = "Brasília"
note        = "It's a great day"

str é uma sequência imutável de code points Unicode, não bytes. len("café") é 4, não 5. A imutabilidade torna as strings hasháveis: válidas como chaves de dict e membros de set. O CPython faz interning de strings curtas que parecem identificadores; duas variáveis atribuídas com o mesmo literal curto frequentemente compartilham um único objeto na memória. Ambos os estilos de aspas produzem objetos idênticos.

python
player_name = "Ana"
city        = "Brasília"
note        = "It's a great day"

Números inteiros (int)

Números inteiros vão sem aspas ou ponto decimal. O Python os chama de integers. Eles podem ser tão grandes quanto você precisar; o Python lida com números arbitrariamente grandes sem nenhum esforço especial da sua parte.

python
score      = 0
age        = 28
population = 8_100_000_000   # underscores são apenas para legibilidade

Inteiros são escritos sem aspas ou pontos decimais. Os inteiros do Python têm precisão arbitrária: eles crescem para conter qualquer valor, diferentemente dos inteiros de tamanho fixo de 32 ou 64 bits em C ou Java. Underscores em literais numéricos são cosméticos e ignorados pelo Python.

python
score      = 0
age        = 28
population = 8_100_000_000

int no Python tem precisão arbitrária: o objeto aloca memória adicional conforme o valor cresce, limitado apenas pela RAM disponível. O CPython armazena em cache inteiros pequenos de -5 a 256 como singletons; id(1) == id(1) é sempre True. Fora dessa faixa, cada literal cria um objeto distinto. É por isso que is dá resultados não confiáveis para comparações de inteiros; sempre use ==.

python
score      = 0
age        = 28
population = 8_100_000_000

Números decimais (float)

Qualquer número com um ponto decimal é um float. Eles funcionam como esperado para a maioria dos cálculos. Uma coisa a saber: alguns valores decimais não podem ser armazenados exatamente em binário, então você pode obter um pequeno erro de arredondamento:

python
price       = 4.99
temperature = 36.6

0.1 + 0.2   # 0.30000000000000004

Para o trabalho do dia a dia isso raramente importa. Para cálculos financeiros onde frações de centavo contam, o Python tem um módulo decimal que lida com isso corretamente. Isso é abordado no capítulo Numbers.

Qualquer número com um ponto decimal se torna um float. Os floats do Python são IEEE 754 binary64: 64 bits com aproximadamente 15-17 dígitos decimais significativos de precisão. O problema bem conhecido: 0.1 + 0.2 é 0.30000000000000004. Não é um bug do Python; é uma consequência da representação binária. Para cálculos financeiros onde decimais exatos importam, o módulo decimal do Python é a ferramenta certa, abordado no capítulo Numbers.

python
price       = 4.99
temperature = 36.6

float mapeia para o double do C: IEEE 754 binary64, mantissa de 53 bits, precisão relativa de 2^-52 ≈ 2.2e-16. Frações cujos denominadores têm fatores primos diferentes de 2 (como 1/10 = 1/(2×5)) não terminam em binário e não podem ser armazenadas exatamente. Para aritmética decimal exata, decimal.Decimal do Python usa base 10 com precisão arbitrária. Para aritmética racional exata, fractions.Fraction armazena pares numerador/denominador. Ambos estão na biblioteca padrão, abordados no capítulo Modules.

python
price       = 4.99
temperature = 36.6

Verdadeiro ou falso (bool)

Algumas coisas são simplesmente ligadas ou desligadas. O Python usa booleans para isso: exatamente dois valores, True e False. Parecem pouca coisa neste estágio, mas toda condição e ramificação no seu programa funciona com base em um booleano.

python
is_logged_in = True
has_errors   = False

O Python também trata certos valores como se fossem False quando usados em uma condição: 0, 0.0, "" e None (o "sem valor aqui" do Python) todos se comportam como False. Todo o resto se comporta como True. Isso se torna útil no capítulo Control flow.

bool contém exatamente True ou False. É retornado por comparações e consumido por condições. O Python tem um conjunto mais amplo de valores truthy e falsy: valores zero, contêineres vazios e None são falsy; todo o resto é truthy. Um detalhe útil: bool é uma subclasse de int, então True + True resulta em 2.

python
is_logged_in = True
has_errors   = False

bool é subclasse de int. True e False são singletons com valores inteiros 1 e 0 respectivamente. Valores falsy: valores zero (0, 0.0), sequências e mapeamentos vazios ("", [], (), {}), None e False. Todo o resto é truthy. Objetos personalizados controlam isso via __bool__ ou __len__. isinstance(True, int) é True, o que importa em código genérico de verificação de tipo.

python
is_logged_in = True
has_errors   = False

Verificando e convertendo tipos

Quando você não tem certeza de qual tipo é um valor, type() te diz. Para verificar se um valor é de um tipo específico, isinstance() é a ferramenta mais confiável:

python
print(type("hello"))   # <class 'str'>
print(type(42))        # <class 'int'>
print(type(3.14))      # <class 'float'>
print(type(True))      # <class 'bool'>

isinstance(42, int)    # True
isinstance("hi", str)  # True

type() retorna o tipo exato de um objeto. Para verificação de tipo no seu próprio código, isinstance() é preferido: ele lida com herança, o que comparações com type() não fazem.

python
print(type(42))          # <class 'int'>
isinstance(True, int)    # True   (bool é uma subclasse de int)
type(True) == int        # False  (apenas correspondência exata, sem subclasses)

type(x) retorna o objeto de tipo de x. isinstance(x, T) percorre a MRO (x.__class__.__mro__), lidando com relações de subclasse que comparações com type() não capturam. O caso prático: isinstance(True, int) é True porque bool é subclasse de int; type(True) == int é False porque é uma verificação exata de identidade. Use isinstance() para guardas de tipo em código de produção.

python
isinstance(True, int)    # True
type(True) == int        # False

O Python não mistura tipos automaticamente. Concatenar uma string e um número gera um TypeError:

python
score = 42
print("Your score is " + score)        # TypeError
print("Your score is " + str(score))   # funciona

Converta explicitamente usando o nome do tipo como uma função:

ChamadaResultado
str(42)"42"
int(3.9)3 (trunca, não arredonda)
float("3.14")3.14
int("3.14")ValueError: não pode converter uma string decimal para int diretamente
int(float("3.14"))3 (converte para float primeiro, depois para int)
bool(0) / bool("")False

Na prática

Os quatro tipos trabalhando juntos em um pequeno script. As linhas de saída usam f-strings para embutir valores no texto: coloque f antes da aspa de abertura e envolva qualquer variável em {}. O Python substitui pelo valor real da variável. Você vai aprendê-las apropriadamente no próximo capítulo.

python
player_name = "Ana"
level       = 3
accuracy    = 0.94
is_premium  = True

print(f"{player_name} is on level {level} with {accuracy:.0%} accuracy.")
print(f"Premium account: {is_premium}")

Os tipos importam porque level + 1 funciona e player_name + 1 não. Cada variável guarda exatamente um tipo de coisa; o Python não vai misturá-los silenciosamente para você.

Um bloco de configuração realista com todos os quatro tipos, constantes separadas do estado em tempo de execução. A sintaxe f"..." é uma f-string: qualquer expressão dentro de {} é avaliada em tempo de execução e embutida na saída. Abordado completamente no capítulo Output and input.

python
BASE_URL    = "https://api.example.com"
MAX_RETRIES = 3
DEBUG       = False

user_name     = "Ana"
request_count = 0
last_response = None

request_count += 1
print(f"[{request_count}] {BASE_URL} | debug={DEBUG}")

None é o marcador padrão para "ainda sem valor". Seu tipo é NoneType e ele se comporta como falsy em condições. Use-o como o padrão para variáveis que ainda não têm significado até mais adiante no programa.

A mesma configuração com anotações de tipo inline. Anotações são documentação para verificadores de tipo e IDEs; elas não têm efeito em tempo de execução:

python
BASE_URL:    str  = "https://api.example.com"
MAX_RETRIES: int  = 3
DEBUG:       bool = False

user_name:     str        = "Ana"
request_count: int        = 0
last_response: str | None = None

str | None é a sintaxe de união do Python 3.10: a variável contém ou uma string ou None. Em versões anteriores, o equivalente é Optional[str] do módulo typing. A forma str | None é preferida no Python moderno quando a versão mínima permite.