Python & AI Tutorials Logo
Programação Python

3. Variáveis e Tipos de Dados Básicos

No Capítulo 2, você aprendeu a escrever programas simples que imprimem texto, aceitam entrada e realizam operações básicas. Porém, esses programas tinham uma limitação importante: eles não conseguiam armazenar informações para uso posterior nem trabalhar com diferentes tipos de dados de maneiras sofisticadas. Neste capítulo, você vai aprender como o Python armazena e gerencia informações usando variáveis e tipos de dados.

Pense em variáveis como recipientes etiquetados que guardam informações. Assim como você pode usar caixas com rótulos para organizar itens na sua casa, o Python usa variáveis para organizar e gerenciar dados nos seus programas. Mas nem todos os dados são iguais—um número é fundamentalmente diferente de texto, e o Python precisa saber com que tipo de dado está lidando. É aí que entram os tipos de dados.

Ao final deste capítulo, você vai entender:

  • Como criar e nomear variáveis corretamente
  • O que são tipos de dados e por que eles importam
  • Como trabalhar com números, texto e valores lógicos
  • Como converter entre diferentes tipos de dados
  • Como o Python representa dados internamente

Esses conceitos formam a base para tudo o que você fará em Python, então vamos explorá-los a fundo e com muitos exemplos práticos.

3.1) Nomeando e Criando Variáveis

3.1.1) O que São Variáveis e Por que São Importantes

Uma variável é um nome que se refere a um valor armazenado na memória do seu computador. Quando você cria uma variável, está essencialmente criando um rótulo que aponta para algum pedaço de dado. Isso permite que você:

  1. Armazene informações para uso posterior no seu programa
  2. Faça referência ao mesmo valor várias vezes sem precisar digitá-lo de novo
  3. Atualize valores enquanto o programa está rodando
  4. Torne seu código legível usando nomes significativos em vez de valores “crus”

Vamos ver um exemplo concreto. Sem variáveis, se você quisesse calcular a área de um retângulo, poderia escrever:

python
# without_variables.py
print("Rectangle area:", 15 * 8)

Isso funciona, mas e se você precisar usar essas dimensões várias vezes? E o que 15 e 8 representam? Com variáveis, o código fica mais claro e flexível:

python
# with_variables.py
length = 15
width = 8
area = length * width
print("Rectangle area:", area)  # Output: Rectangle area: 120

Agora o código é autoexplicativo—qualquer pessoa lendo consegue entender imediatamente que estamos calculando a área de um retângulo com dimensões específicas. Se precisarmos mudar as dimensões, basta atualizar as atribuições de variáveis no topo.

3.1.2) Criando Variáveis com Atribuição

Em Python, você cria uma variável usando o operador de atribuição (=). A sintaxe básica é:

python
variable_name = value

O sinal = não significa “igual” no sentido matemático. Em vez disso, significa “atribua o valor à direita ao nome à esquerda”. Essa distinção é crucial. Quando o Python vê essa instrução, ele:

  1. Avalia a expressão no lado direito do =
  2. Cria ou atualiza o nome de variável no lado esquerdo
  3. Faz esse nome se referir ao valor resultante

Aqui estão vários exemplos de criação de variáveis:

python
# creating_variables.py
age = 25
temperature = 72.5
name = "Alice"
is_student = True
 
print(age)          # Output: 25
print(temperature)  # Output: 72.5
print(name)         # Output: Alice
print(is_student)   # Output: True

Perceba que não precisamos declarar que tipo de dado cada variável vai guardar—o Python descobre isso automaticamente com base no valor que você atribui. Isso é chamado de tipagem dinâmica (dynamic typing), e torna o Python muito flexível e fácil de usar.

Você também pode criar múltiplas variáveis em uma única linha usando atribuição múltipla:

python
# multiple_assignment.py
x, y, z = 10, 20, 30
print(x)  # Output: 10
print(y)  # Output: 20
print(z)  # Output: 30
 
# You can even assign the same value to multiple variables
a = b = c = 100
print(a, b, c)  # Output: 100 100 100

A primeira forma (chamada de tuple unpacking—vamos aprender sobre tuplas no Capítulo 14) atribui cada valor à variável correspondente na ordem. A segunda forma atribui o mesmo valor a todas as três variáveis.

3.1.3) Regras e Convenções para Nomear Variáveis

O Python tem regras específicas sobre o que compõe um nome de variável válido. Algumas são obrigatórias (regras que você precisa seguir), enquanto outras são convenções (diretrizes que tornam seu código mais legível e consistente com outros códigos Python).

Requisitos (Obrigatórios):

  1. Deve começar com uma letra (a-z, A-Z) ou sublinhado (_): nomes de variáveis não podem começar com dígito.
  2. Pode conter letras, dígitos e sublinhados: depois do primeiro caractere, você pode usar letras, números e sublinhados em qualquer combinação.
  3. Não pode conter espaços ou caracteres especiais: espaços, hifens e a maioria dos sinais de pontuação não são permitidos.
  4. Não pode ser uma palavra reservada do Python (keyword): o Python reserva certas palavras para seu próprio uso (como if, for, while, def, etc.).
  5. Case-sensitive (sensível a maiúsculas/minúsculas): age, Age e AGE são três variáveis diferentes.

Aqui estão exemplos de nomes de variáveis válidos e inválidos:

python
# valid_names.py
# Valid variable names
user_age = 30
firstName = "John"
total_2024 = 1000
_private = "hidden"
x = 5
MAX_SIZE = 100
 
# Invalid variable names (these will cause errors)
# 2nd_place = "silver"      # Error: starts with digit
# user-name = "alice"       # Error: contains hyphen
# total amount = 500        # Error: contains space
# class = "Python 101"      # Error: 'class' is a keyword

Convenções (Devem ser seguidas para legibilidade):

  1. Use letras minúsculas com sublinhados para variáveis comuns: esse estilo é chamado de snake_case e é o padrão em Python.

    python
    user_age = 25
    total_price = 99.99
    is_valid = True
  2. Use MAIÚSCULAS para constantes: valores que não deveriam mudar durante a execução do programa.

    python
    MAX_ATTEMPTS = 3
    PI = 3.14159
    DEFAULT_COLOR = "blue"
  3. Use nomes descritivos: nomes de variáveis devem indicar claramente o que representam.

    python
    # Good: clear and descriptive
    student_count = 30
    average_temperature = 72.5
     
    # Poor: unclear abbreviations
    sc = 30
    avg_tmp = 72.5
     
    # Poor: too generic
    x = 30
    data = 72.5
  4. Evite nomes de uma letra, exceto em casos específicos: letras únicas como i, j, k são aceitáveis como contadores de loop (loop) (vamos aprender sobre isso no Capítulo 11), e x, y, z são ok para coordenadas. Fora isso, prefira nomes descritivos.

  5. Não use nomes que sombreiem funções embutidas (built-ins): embora o Python permita, evite usar nomes como list, str, int, print, etc., pois são nomes de funções embutidas.

Vamos ver um exemplo prático que demonstra boas práticas de nomeação:

python
# good_naming.py
# Constants at the top
SALES_TAX_RATE = 0.08
DISCOUNT_THRESHOLD = 100
 
# Descriptive variable names
item_price = 75.00
quantity = 3
subtotal = item_price * quantity
 
# Clear boolean variable
qualifies_for_discount = subtotal >= DISCOUNT_THRESHOLD
 
if qualifies_for_discount:
    discount = subtotal * 0.10
    subtotal = subtotal - discount
    print("Discount applied: $", discount)
 
tax = subtotal * SALES_TAX_RATE
total = subtotal + tax
 
print("Subtotal: $", subtotal)
print("Tax: $", tax)
print("Total: $", total)
# Output:
# Subtotal: $ 202.5
# Tax: $ 16.2
# Total: $ 218.7

Perceba como os nomes das variáveis tornam o código autoexplicativo. Mesmo sem comentários, você consegue entender o que o programa está calculando.

3.1.4) Usando Variáveis em Expressões

Depois que você cria uma variável, pode usá-la em qualquer lugar em que usaria o valor que ela representa. O Python substitui automaticamente o valor atual da variável ao avaliar expressões:

python
# using_variables.py
# Create some variables
hours_worked = 40
hourly_rate = 25.50
 
# Use variables in calculations
gross_pay = hours_worked * hourly_rate
print("Gross pay:", gross_pay)  # Output: Gross pay: 1020.0
 
# Use variables in other expressions
bonus = gross_pay * 0.10
total_pay = gross_pay + bonus
print("Total with bonus:", total_pay)  # Output: Total with bonus: 1122.0
 
# Use variables in strings (we'll learn more about this in Chapter 5)
message = "You worked " + str(hours_worked) + " hours"
print(message)  # Output: You worked 40 hours

Variáveis também podem ser usadas com as funções que você aprendeu no Capítulo 2:

python
# variables_with_functions.py
name = input("What is your name? ")
age = input("What is your age? ")
 
greeting = "Hello, " + name + "!"
print(greeting)
 
age_next_year = int(age) + 1
print("Next year you will be", age_next_year, "years old.")
# If user enters "Alice" and "25":
# Output: Hello, Alice!
# Output: Next year you will be 26 years old.

Esse exemplo também demonstra um conceito importante: a função input() sempre retorna texto (uma string), então se você quiser fazer contas com esse valor, precisa convertê-lo para número antes. Vamos explorar esse processo de conversão em detalhes mais adiante neste capítulo (Seção 3.7).

3.2) Atribuição e Reatribuição de Variáveis

3.2.1) Entendendo Atribuição

Quando você atribui um valor a uma variável, o Python cria uma conexão entre o nome da variável e o valor na memória. É importante entender que a variável não “contém” o valor em um sentido físico—em vez disso, é um nome que se refere ou aponta para um valor armazenado em outro lugar na memória.

Pense nisso como um post-it com um nome escrito, colado em uma caixa que contém o valor real. A variável (post-it) não é o valor em si—ela apenas aponta para onde o valor está armazenado. Quando você reatribui a variável, está movendo o post-it para apontar para outra caixa, não mudando o que está na caixa original.

Essa distinção se torna importante quando falamos de reatribuição. Vamos explorar o que acontece quando você atribui e reatribui variáveis:

python
# assignment_basics.py
x = 10
print(x)  # Output: 10
 
# Reassign x to a new value
x = 20
print(x)  # Output: 20
 
# The old value (10) is gone; x now refers to 20

Veja o que aconteceu passo a passo:

  1. x = 10: o Python cria o valor inteiro 10 na memória e faz o nome x referir-se a ele
  2. print(x): o Python procura para o que x se refere (10) e imprime
  3. x = 20: o Python cria o valor inteiro 20 na memória e faz x referir-se a esse novo valor
  4. print(x): o Python procura para o que x se refere (agora 20) e imprime

O valor original 10 ainda existe na memória temporariamente, mas como nenhuma variável se refere mais a ele, o gerenciamento automático de memória do Python (chamado garbage collection) eventualmente vai limpá-lo.

3.2.2) Reatribuição e Atualização de Variáveis

Um dos padrões mais comuns em programação é atualizar uma variável com base em seu valor atual. Por exemplo, você pode querer aumentar um contador, somar a um total acumulado ou modificar um valor com base em algum cálculo:

python
# updating_variables.py
score = 0
print("Initial score:", score)  # Output: Initial score: 0
 
# Add 10 points
score = score + 10
print("After first update:", score)  # Output: After first update: 10
 
# Add 5 more points
score = score + 5
print("After second update:", score)  # Output: After second update: 15
 
# Double the score
score = score * 2
print("After doubling:", score)  # Output: After doubling: 30

Vamos detalhar o que acontece em score = score + 10:

  1. O Python avalia o lado direito: score + 10
  2. Ele procura o valor atual de score (0)
  3. Calcula 0 + 10, obtendo 10
  4. Atribui esse novo valor (10) à variável score
  5. Agora score se refere a 10 em vez de 0

Esse padrão é tão comum que o Python fornece operadores encurtados para isso, que vamos aprender no Capítulo 4 (Seção 4.3). Mas, por enquanto, é importante entender a forma completa, pois ela mostra claramente a ordem das operações: avalie completamente o lado direito, depois atribua ao lado esquerdo.

3.2.3) Variáveis São Independentes

Quando você atribui uma variável a outra, o Python copia a referência, não o valor em si (para tipos simples como números e strings). Porém, para os tipos básicos que estamos aprendendo neste capítulo, as variáveis se comportam de forma independente depois da atribuição:

python
# independent_variables.py
a = 10
b = a  # b now refers to the same value as a (10)
print("a:", a)  # Output: a: 10
print("b:", b)  # Output: b: 10
 
# Change a
a = 20
print("After changing a:")
print("a:", a)  # Output: a: 20
print("b:", b)  # Output: b: 10 (unchanged!)

Quando fizemos b = a, fizemos b referir-se ao mesmo valor para o qual a se referia naquele momento (10). Quando mais tarde mudamos a para se referir a 20, b permaneceu inalterada—ela ainda se refere a 10.

Esse comportamento é simples para números e strings, mas fica mais complexo com coleções como listas (list) e dicionários. Vamos explorar isso a fundo no Capítulo 17, quando discutirmos o modelo de objetos do Python e a semântica de referências.

3.2.4) Usando Variáveis Antes da Atribuição

Um erro comum de iniciantes é tentar usar uma variável antes de ela ter recebido um valor. O Python vai gerar um NameError se você tentar fazer isso:

python
# undefined_variable.py
print(total)  # Error: NameError: name 'total' is not defined

Esse erro ocorre porque o Python não sabe a que total se refere—você ainda não a criou. A correção é simples: atribua um valor à variável antes de usá-la:

python
# defined_variable.py
total = 0  # Initialize the variable first
print(total)  # Output: 0
 
# Now we can update it
total = total + 10
print(total)  # Output: 10

Esse padrão de inicializar uma variável (dar a ela um valor inicial) antes de usá-la é fundamental em programação. Vamos ver muitos exemplos disso ao longo do livro, especialmente ao trabalhar com contadores e acumuladores em loops (Capítulo 10).

3.2.5) Trocando Valores de Variáveis

Uma operação comum é trocar os valores de duas variáveis. Em muitas linguagens de programação, isso exige uma variável temporária:

python
# swap_with_temp.py
x = 10
y = 20
print("Before swap: x =", x, ", y =", y)  # Output: Before swap: x = 10 , y = 20
 
# Swap using a temporary variable
temp = x    # Save x's value
x = y       # Put y's value in x
y = temp    # Put saved value in y
 
print("After swap: x =", x, ", y =", y)  # Output: After swap: x = 20 , y = 10

Porém, o Python fornece uma forma mais elegante usando atribuição simultânea:

python
# swap_pythonic.py
x = 10
y = 20
print("Before swap: x =", x, ", y =", y)  # Output: Before swap: x = 10 , y = 20
 
# Swap in one line
x, y = y, x
 
print("After swap: x =", x, ", y =", y)  # Output: After swap: x = 20 , y = 10

Isso funciona porque o Python avalia todo o lado direito (y, x) antes de fazer qualquer atribuição. Assim, ele cria uma estrutura temporária contendo os valores de y e x, e depois desempacota esses valores em x e y, respectivamente. Esse é um bom exemplo da filosofia do Python de tornar operações comuns simples e legíveis.

3.3) O Conceito de Tipos de Dados e type()

3.3.1) O que São Tipos de Dados?

Um tipo de dado (ou simplesmente tipo) define que tipo de informação um valor representa e quais operações podem ser realizadas sobre ele. Pense em tipos de dados como categorias que dizem ao Python como interpretar e trabalhar com diferentes tipos de informação.

Por exemplo:

  • O número 42 é um inteiro (número inteiro)
  • O número 3.14 é um número de ponto flutuante (número com ponto decimal)
  • O texto "Hello" é uma string (sequência de caracteres)
  • O valor True é um booleano (valor lógico verdadeiro/falso)

Por que tipos de dados importam? Porque tipos diferentes suportam operações diferentes:

python
# type_operations.py
# You can add numbers
result1 = 10 + 5
print(result1)  # Output: 15
 
# You can also "add" strings (concatenation)
result2 = "Hello" + " " + "World"
print(result2)  # Output: Hello World
 
# But you can't add a number and a string directly
# result3 = 10 + "5"  # Error: TypeError: unsupported operand type(s)

O erro no último exemplo ocorre porque o Python não sabe como somar um número e uma string—eles são tipos de dados fundamentalmente diferentes. Ele deveria converter o número para texto e concatenar? Ou deveria converter o texto para número e somar matematicamente? O Python exige que você seja explícito sobre o que quer, convertendo um valor para o tipo do outro (vamos aprender como fazer isso na Seção 3.7).

3.3.2) Usando type() para Verificar Tipos de Dados

O Python fornece uma função embutida chamada type() que informa qual é o tipo de um valor ou variável. Isso é extremamente útil para entender seus dados e depurar problemas:

python
# checking_types.py
# Check types of literal values
print(type(42))        # Output: <class 'int'>
print(type(3.14))      # Output: <class 'float'>
print(type("Hello"))   # Output: <class 'str'>
print(type(True))      # Output: <class 'bool'>
 
# Check types of variables
age = 25
name = "Alice"
temperature = 98.6
is_valid = False
 
print(type(age))         # Output: <class 'int'>
print(type(name))        # Output: <class 'str'>
print(type(temperature)) # Output: <class 'float'>
print(type(is_valid))    # Output: <class 'bool'>

A saída <class 'int'> significa “esse valor pertence à classe (tipo) chamada int”. Em Python, tipos são na verdade classes (vamos aprender sobre classes em detalhes na Parte VIII), mas por enquanto você pode pensar nesses termos como sinônimos.

3.3.3) Tipagem Dinâmica em Python

O Python é uma linguagem de tipagem dinâmica (dynamically typed), o que significa:

  1. Variáveis não têm tipos fixos: uma variável pode referir-se a valores de tipos diferentes em momentos diferentes
  2. Os tipos são determinados em tempo de execução: o Python descobre os tipos quando o programa roda, não quando você escreve o código
  3. Você não declara tipos explicitamente: ao contrário de algumas outras linguagens, você não precisa dizer “esta variável vai guardar um inteiro”

Aqui está um exemplo de tipagem dinâmica em ação:

python
# dynamic_typing.py
x = 42
print(x, "is of type", type(x))  # Output: 42 is of type <class 'int'>
 
x = "Hello"
print(x, "is of type", type(x))  # Output: Hello is of type <class 'str'>
 
x = 3.14
print(x, "is of type", type(x))  # Output: 3.14 is of type <class 'float'>

Perceba como x pode se referir a tipos diferentes de valores em momentos diferentes do programa. O Python não reclama—ele simplesmente atualiza para qual tipo x está se referindo no momento.

Embora essa flexibilidade seja conveniente, ela também exige cuidado. Se você espera que uma variável guarde um número, mas na verdade ela guarda uma string, pode acabar com erros inesperados:

python
# type_confusion.py
value = "100"  # This is a string, not a number!
 
# Trying to do math with it will fail
# result = value + 50  # Error: TypeError: can only concatenate str to str
 
# You need to convert it first
result = int(value) + 50
print(result)  # Output: 150

É por isso que entender tipos de dados é crucial—isso ajuda você a prever quais operações vão funcionar e a detectar erros antes que causem problemas.

3.3.4) Visão Geral dos Tipos Embutidos do Python

O Python tem vários tipos de dados embutidos. Neste capítulo, vamos focar nos mais fundamentais:

Python Built-in Types

Numeric Types

Text Type

Boolean Type

None Type

Collection Types

int: Integers

float: Decimal Numbers

complex: Complex Numbers

str: Text/Strings

bool: True/False

NoneType: None

list, tuple, dict, set...

Neste capítulo, vamos ver:

  • int: Integer numbers (whole numbers)
  • float: Floating-point numbers (numbers with decimal points)
  • str: Strings (text)
  • bool: Boolean values (True and False)
  • NoneType: The special value None

Vamos mencionar brevemente números complex (números com parte imaginária), mas eles raramente são necessários em programação do dia a dia. Os tipos de coleção (como listas (list), tuplas, dicionários e conjuntos) são tão importantes que dedicamos capítulos inteiros a eles na Parte IV.

3.3.5) Verificação de Tipo na Prática

Entender tipos fica especialmente importante ao trabalhar com entrada do usuário ou dados de fontes externas. Lembre-se de que input() sempre retorna uma string, mesmo que o usuário digite um número:

python
# input_types.py
user_input = input("Enter a number: ")
print("You entered:", user_input)
print("Type:", type(user_input))  # Output: Type: <class 'str'>
 
# Even if user types "42", it's still a string!
# To use it as a number, convert it:
number = int(user_input)
print("As a number:", number)
print("Type:", type(number))  # Output: Type: <class 'int'>
 
# Now we can do math with it
doubled = number * 2
print("Doubled:", doubled)

Quando você executa esse programa e digita 42, verá:

Enter a number: 42
You entered: 42
Type: <class 'str'>
As a number: 42
Type: <class 'int'>
Doubled: 84

Isso demonstra um ponto crucial: a string "42" e o inteiro 42 são coisas diferentes em Python, embora pareçam semelhantes quando impressos. A string é uma sequência de dois caracteres ('4' e '2'), enquanto o inteiro é um valor numérico que pode ser usado em operações matemáticas.

3.4) Números Inteiros e de Ponto Flutuante

3.4.1) Inteiros (int)

Um inteiro (tipo int) é um número inteiro sem ponto decimal. Inteiros podem ser positivos, negativos ou zero e, no Python 3, podem ser arbitrariamente grandes—limitados apenas pela memória disponível do seu computador.

python
# integers.py
# Positive integers
age = 25
year = 2024
population = 8000000000
 
# Negative integers
temperature = -15
debt = -5000
 
# Zero
balance = 0
 
# Very large integers (Python handles these easily)
huge_number = 123456789012345678901234567890
print(huge_number)  # Output: 123456789012345678901234567890
print(type(huge_number))  # Output: <class 'int'>

O Python permite escrever números grandes com sublinhados para facilitar a leitura. Os sublinhados são ignorados pelo Python, mas tornam os números mais fáceis de ler para humanos:

python
# readable_numbers.py
# These are all the same number
million = 1000000
million = 1_000_000  # Much easier to read!
 
# Works with any size
population = 8_000_000_000
national_debt = 31_000_000_000_000
 
print(million)      # Output: 1000000 (underscores not shown in output)
print(population)   # Output: 8000000000

Você também pode escrever inteiros em bases numéricas diferentes usando prefixos especiais:

python
# number_bases.py
# Binary (base 2) - prefix 0b
binary = 0b1010  # This is 10 in decimal
print(binary)  # Output: 10
 
# Octal (base 8) - prefix 0o
octal = 0o12  # This is 10 in decimal
print(octal)  # Output: 10
 
# Hexadecimal (base 16) - prefix 0x
hexadecimal = 0xFF  # This is 255 in decimal
print(hexadecimal)  # Output: 255

Essas bases alternativas são úteis em certos contextos (como trabalhar com cores em web ou programação de baixo nível), mas na maior parte da programação do dia a dia você usará inteiros decimais comuns.

3.4.2) Números de Ponto Flutuante (float)

Um número de ponto flutuante (tipo float) é um número com ponto decimal. Floats são usados para representar números reais—valores que não são necessariamente inteiros:

python
# floats.py
# Numbers with decimal points
price = 19.99
temperature = 98.6
pi = 3.14159
 
# Very small numbers
electron_mass = 0.00000000000000000000000000000091093837
 
# Very large numbers
speed_of_light = 299792458.0
 
print(price)           # Output: 19.99
print(temperature)     # Output: 98.6
print(electron_mass)   # Output: 9.1093837e-31 (scientific notation)
print(speed_of_light)  # Output: 299792458.0

Perceba que floats muito pequenos ou muito grandes são exibidos em notação científica (também chamada notação exponencial). A notação 9.1093837e-31 significa “9.1093837 × 10⁻³¹” ou “9.1093837 dividido por 10 elevado à potência 31”.

Você também pode escrever floats usando notação científica diretamente:

python
# scientific_notation.py
# These are equivalent
avogadro = 602214076000000000000000.0
avogadro = 6.02214076e23  # Much more readable!
 
# Small numbers
planck = 0.000000000000000000000000000000000662607015
planck = 6.62607015e-34  # Much more readable!
 
print(avogadro)  # Output: 6.02214076e+23
print(planck)    # Output: 6.62607015e-34

O e (ou E) significa “expoente”. O número depois do e diz quantas casas mover o ponto decimal (positivo significa para a direita, negativo para a esquerda).

3.4.3) Inteiro vs Float: Diferenças Importantes

Embora inteiros e floats representem números, eles têm diferenças importantes:

1. Precisão e Representação:

Inteiros são exatos—o valor 42 é exatamente 42, sem aproximação. Floats, por outro lado, são aproximações por causa de como computadores armazenam números decimais em binário:

python
# float_precision.py
# This might surprise you!
result = 0.1 + 0.2
print(result)  # Output: 0.30000000000000004
 
# The result isn't exactly 0.3 due to floating-point representation
print(result == 0.3)  # Output: False

Isso não é um bug—é uma limitação fundamental de como computadores representam números decimais. Vamos discutir isso em mais detalhes no Capítulo 4 (Seção 4.10), mas por enquanto, apenas saiba que cálculos com float podem não ser perfeitamente precisos.

2. Operações e Resultados:

Quando você realiza operações com inteiros e floats, o Python segue regras específicas:

python
# int_float_operations.py
# Integer operations
int_result = 10 + 5
print(int_result, type(int_result))  # Output: 15 <class 'int'>
 
# Float operations
float_result = 10.0 + 5.0
print(float_result, type(float_result))  # Output: 15.0 <class 'float'>
 
# Mixed operations: result is always float
mixed_result = 10 + 5.0
print(mixed_result, type(mixed_result))  # Output: 15.0 <class 'float'>
 
# Division always returns float, even with integers
division_result = 10 / 5
print(division_result, type(division_result))  # Output: 2.0 <class 'float'>

A regra principal: qualquer operação envolvendo pelo menos um float produz um resultado float. Isso faz sentido porque floats podem representar uma faixa mais ampla de valores (incluindo números não inteiros), então o Python “promove” o resultado para o tipo mais geral.

3. Memória e Desempenho:

Inteiros usam menos memória e são mais rápidos de calcular do que floats. Para a maioria dos programas, essa diferença é irrelevante, mas pode importar em aplicações de alto desempenho ou com conjuntos de dados muito grandes.

3.4.4) Quando Usar int vs float

Aqui vão diretrizes práticas para escolher entre inteiros e floats:

Use inteiros quando:

  • Estiver contando itens discretos (pessoas, objetos, iterações)
  • Representar quantidades exatas que não podem ser fracionárias (número de alunos, número de cliques)
  • Trabalhar com índices ou posições em sequências
  • Aritmética exata for necessária
python
# use_integers.py
student_count = 30  # Can't have 30.5 students
page_number = 42    # Can't be on page 42.7
loop_counter = 0    # Counting iterations

Use floats quando:

  • Representar medições (temperatura, distância, peso)
  • Trabalhar com dinheiro (embora seja preciso cuidado com precisão—vamos discutir isso no Capítulo 4)
  • Calcular razões, porcentagens ou médias
  • Valores aproximados forem aceitáveis
python
# use_floats.py
temperature = 72.5     # Temperature can be fractional
price = 19.99          # Money amounts have cents
average_score = 87.3   # Averages are often fractional
percentage = 0.15      # 15% as a decimal

3.5) Literais de String e Booleanos (Uma Prévia Rápida)

Nesta seção, vamos apresentar rapidamente mais dois tipos de dados fundamentais: strings e booleanos. Vamos ver strings em muito mais profundidade nos Capítulos 5 e 6, e booleanos em detalhes no Capítulo 7, mas você precisa de uma noção básica deles agora para escrever até mesmo programas simples.

3.5.1) Noções Básicas de String

Uma string (tipo str) é uma sequência de caracteres—basicamente, texto. Você cria strings envolvendo texto em aspas. O Python aceita aspas simples (') ou aspas duplas ("):

python
# string_basics.py
# Single quotes
name = 'Alice'
message = 'Hello, World!'
 
# Double quotes (exactly equivalent)
name = "Alice"
message = "Hello, World!"
 
# Print them
print(name)     # Output: Alice
print(message)  # Output: Hello, World!
print(type(name))  # Output: <class 'str'>

Aspas simples e duplas funcionam de forma idêntica—escolha a que você preferir, mas seja consistente dentro do seu código. Muitos programadores Python preferem aspas duplas porque são mais comuns em outras linguagens, mas aspas simples são igualmente válidas.

Por que existem as duas? O principal motivo é a conveniência quando sua string contém aspas:

python
# quotes_in_strings.py
# Use double quotes when string contains single quotes
sentence = "It's a beautiful day!"
print(sentence)  # Output: It's a beautiful day!
 
# Use single quotes when string contains double quotes
speech = 'She said, "Hello!"'
print(speech)  # Output: She said, "Hello!"
 
# Or use escape sequences (we'll learn more in Chapter 5)
sentence = 'It\'s a beautiful day!'  # \' means a literal single quote
speech = "She said, \"Hello!\""     # \" means a literal double quote

Strings podem ser vazias (não conter caractere nenhum):

python
# empty_string.py
empty = ""
also_empty = ''
 
print(empty)            # Output: (nothing—it's empty!)
print(len(empty))       # Output: 0 (we'll learn about len() later)
print(type(empty))      # Output: <class 'str'>

Você pode combinar strings usando o operador + (isso é chamado de concatenação):

python
# string_concatenation.py
first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name
print(full_name)  # Output: John Doe
 
# Be careful: you can't concatenate strings and numbers directly
age = 25
# message = "I am " + age + " years old"  # Error: TypeError
 
# Convert the number to a string first
message = "I am " + str(age) + " years old"
print(message)  # Output: I am 25 years old

Vamos explorar strings muito mais a fundo nos Capítulos 5 e 6, incluindo sequências de escape, métodos de string, formatação e processamento de texto. Por enquanto, lembre-se apenas de que strings representam texto e são criadas com aspas.

3.5.2) Noções Básicas de Booleano

Um booleano (tipo bool) é um valor lógico que pode ser True ou False. Esses são os únicos dois valores booleanos em Python, e são usados para representar verdadeiro e falso em operações lógicas:

python
# boolean_basics.py
# Boolean literals
is_sunny = True
is_raining = False
 
print(is_sunny)         # Output: True
print(is_raining)       # Output: False
print(type(is_sunny))   # Output: <class 'bool'>

Importante: Os valores booleanos True e False devem ser escritos exatamente com essa capitalização. O Python diferencia maiúsculas e minúsculas, então true, TRUE, false e FALSE não funcionam:

python
# boolean_case.py
correct = True    # Correct
# wrong = true    # Error: NameError: name 'true' is not defined
# wrong = TRUE    # Error: NameError: name 'TRUE' is not defined

Booleanos normalmente surgem de comparações ou operações lógicas:

python
# boolean_from_comparisons.py
age = 25
 
# Comparison operators produce boolean results
is_adult = age >= 18
print(is_adult)  # Output: True
 
is_senior = age >= 65
print(is_senior)  # Output: False
 
# You can use booleans in conditions (we'll learn more in Chapter 8)
if is_adult:
    print("You can vote!")  # Output: You can vote!
 
if is_senior:
    print("You get a senior discount!")  # (no output—condition is False)

Operadores de comparação comuns que produzem booleanos:

  • == : igual a
  • != : diferente de
  • < : menor que
  • > : maior que
  • <= : menor ou igual a
  • >= : maior ou igual a
python
# comparison_operators.py
x = 10
y = 20
 
print(x == y)   # Output: False (10 is not equal to 20)
print(x != y)   # Output: True (10 is not equal to 20)
print(x < y)    # Output: True (10 is less than 20)
print(x > y)    # Output: False (10 is not greater than 20)
print(x <= 10)  # Output: True (10 is less than or equal to 10)
print(y >= 20)  # Output: True (20 is greater than or equal to 20)

Nota importante: Não confunda = (atribuição) com == (comparação):

  • x = 10 significa “atribua o valor 10 a x”
  • x == 10 significa “verifique se x é igual a 10” (gera True ou False)
python
# assignment_vs_comparison.py
x = 10        # Assignment: x now refers to 10
result = (x == 10)  # Comparison: is x equal to 10?
print(result)  # Output: True
 
# This is a common mistake for beginners:
# if x = 10:  # Error: SyntaxError (can't use assignment in if condition)
if x == 10:   # Correct: comparison
    print("x is 10")  # Output: x is 10

Vamos explorar booleanos em muito mais detalhes no Capítulo 7, incluindo operadores lógicos (and, or, not), verdade e falsidade (truthiness/falsiness) e como o Python usa booleanos em condições. Por enquanto, lembre-se apenas de que booleanos representam valores True/False e normalmente surgem de comparações.

3.5.3) Strings e Booleanos em Contexto

Vamos ver como strings e booleanos funcionam juntos em um exemplo prático simples:

python
# strings_booleans_example.py
# Get user input
name = input("What is your name? ")
age_input = input("What is your age? ")
 
# Convert age to integer
age = int(age_input)
 
# Create boolean conditions
is_adult = age >= 18
is_child = age < 13
 
# Build messages using strings
if is_adult:
    status = "adult"
else:
    status = "minor"
 
# Combine everything in output
print("Hello, " + name + "!")
print("You are an " + status + ".")
 
if is_child:
    print("You are a child.")
 
# When user enters "Alice" and "16":
# Output: Hello, Alice!
# Output: You are a minor.

Esse exemplo demonstra como diferentes tipos de dados trabalham juntos: strings para texto, inteiros para números e booleanos para decisões lógicas. Essa interação entre tipos é fundamental para toda programação.

3.6) O Valor None e Seus Usos

3.6.1) O que é None?

O Python tem um valor especial chamado None (tipo NoneType) que representa a ausência de valor. É a forma do Python dizer “não há nada aqui” ou “isso ainda não tem valor”.

python
# none_basics.py
result = None
print(result)        # Output: None
print(type(result))  # Output: <class 'NoneType'>

None não é o mesmo que zero, uma string vazia ou False—é um valor distinto que significa especificamente “nenhum valor”:

python
# none_vs_others.py
x = None
y = 0
z = ""
w = False
 
print(x)  # Output: None
print(y)  # Output: 0
print(z)  # Output: (empty—nothing prints)
print(w)  # Output: False
 
# They're all different types
print(type(x))  # Output: <class 'NoneType'>
print(type(y))  # Output: <class 'int'>
print(type(z))  # Output: <class 'str'>
print(type(w))  # Output: <class 'bool'>

3.6.2) Quando None é Usado

None aparece em várias situações comuns:

1. Como placeholder para valores que serão atribuídos depois:

python
# none_placeholder.py
# Initialize variables that will be assigned later
user_name = None
user_age = None
 
# Later in the program, after getting user input:
user_name = input("Enter your name: ")
user_age = int(input("Enter your age: "))
 
print("Name:", user_name)
print("Age:", user_age)

2. Como valor de retorno padrão de funções que não retornam nada explicitamente:

Funções que veremos no Capítulo 19 podem retornar valores. Se uma função não retornar nada explicitamente, o Python retorna None automaticamente:

python
# none_from_function.py
# The print() function returns None
result = print("Hello!")  # Output: Hello!
print(result)             # Output: None
print(type(result))       # Output: <class 'NoneType'>

Isso pode parecer estranho, mas é útil. Significa que toda função retorna algo, mesmo que esse algo seja “nenhum valor significativo”.

3. Para representar dados opcionais ou ausentes:

python
# none_optional.py
# Representing optional middle name
first_name = "John"
middle_name = None  # No middle name
last_name = "Doe"
 
if middle_name is None:
    full_name = first_name + " " + last_name
else:
    full_name = first_name + " " + middle_name + " " + last_name
 
print(full_name)  # Output: John Doe

3.6.3) Verificando se Algo é None

Para verificar se um valor é None, use o operador is (não ==):

python
# checking_none.py
value = None
 
# Correct way: use 'is'
if value is None:
    print("Value is None")  # Output: Value is None
 
# Also correct: use 'is not'
if value is not None:
    print("Value has a value")
else:
    print("Value is None")  # Output: Value is None
 
# While == works, 'is' is preferred for None
if value == None:  # This works but is not idiomatic Python
    print("Value is None")  # Output: Value is None

Por que usar is em vez de ==? O operador is verifica se dois nomes se referem ao mesmo objeto na memória (vamos aprender mais sobre isso no Capítulo 17). Como existe apenas um objeto None em Python, is é mais eficiente e mais preciso para essa verificação. Usar is None é o padrão idiomático em Python.

3.6.4) None no Uso Prático

Aqui está um exemplo prático mostrando como None é útil em programas reais:

python
# none_practical.py
# Simulate looking up a user's age
# (In real programs, we'd use functions and dictionaries from later chapters)
 
user_name = input("Enter a name (Alice, Bob, or Charlie): ")
 
# Check each name and assign age or None
if user_name == "Alice":
    user_age = 25
elif user_name == "Bob":
    user_age = 30
elif user_name == "Charlie":
    user_age = 35
else:
    user_age = None  # User not found
 
# Check if we found the user
if user_age is not None:
    print(user_name, "is", user_age, "years old")
else:
    print(user_name, "not found")
 
# When user enters "Alice":
# Output: Alice is 25 years old
# When user enters "David":
# Output: David not found

Nesse exemplo, None indica claramente “usuário não encontrado”, o que é diferente de encontrar um usuário com idade 0 (que seria uma idade válida para um recém-nascido).

3.6.5) None vs Valores Vazios

É importante diferenciar None de valores vazios:

python
# none_vs_empty.py
# These are all different
nothing = None
zero = 0
empty_string = ""
# Note: We'll learn about lists in Chapter 13
# empty_list = []
 
print(nothing is None)       # Output: True
print(zero is None)          # Output: False
print(empty_string is None)  # Output: False
 
# None means "no value"
# 0 means "the number zero"
# "" means "text with no characters"

Cada um representa um conceito diferente:

  • None: ausência de valor
  • 0: um valor numérico específico (zero)
  • "": uma string que existe, mas não contém caracteres

Entender essa distinção vai ajudar você a escrever programas mais claros e corretos.

3.7) Conversão Básica de Tipos com int(), float() e str()

3.7.1) Por que a Conversão de Tipos é Necessária

Como vimos, o Python tem regras rígidas sobre quais operações funcionam com quais tipos. Você não pode somar um número e uma string, multiplicar uma string por um float ou realizar operações matemáticas sobre texto. Quando você precisa usar um valor como outro tipo, precisa convertê-lo explicitamente.

Conversão de tipo (também chamada de type casting) é o processo de transformar um valor de um tipo para outro. O Python fornece funções embutidas para as conversões mais comuns:

  • int(): converte para inteiro
  • float(): converte para número de ponto flutuante
  • str(): converte para string

Vamos explorar cada uma em detalhes.

3.7.2) Convertendo para Inteiro com int()

A função int() converte um valor para inteiro. Aqui estão os usos principais:

Convertendo floats para inteiros:

python
# float_to_int.py
# int() truncates (cuts off) the decimal part
x = int(3.14)
y = int(3.99)
z = int(-2.7)
 
print(x)  # Output: 3 (not 4—it doesn't round!)
print(y)  # Output: 3 (not 4—it truncates!)
print(z)  # Output: -2 (truncates toward zero)

Importante: int() não arredonda—ele simplesmente remove a parte decimal (trunca em direção a zero). Esse é um ponto de confusão comum para iniciantes que esperam que int(3.9) retorne 4.

Convertendo strings para inteiros:

Isso é extremamente comum ao trabalhar com entrada do usuário:

python
# string_to_int.py
# Convert string containing a number
age_str = "25"
age_int = int(age_str)
 
print(age_str, type(age_str))  # Output: 25 <class 'str'>
print(age_int, type(age_int))  # Output: 25 <class 'int'>
 
# Now we can do math with it
next_year = age_int + 1
print("Next year:", next_year)  # Output: Next year: 26
 
# Practical example with input()
user_age = int(input("Enter your age: "))
print("In 10 years, you'll be", user_age + 10)

O que acontece em conversões inválidas?

Se você tentar converter uma string que não representa um inteiro válido, o Python gera um ValueError:

python
# invalid_int_conversion.py
# These work
print(int("123"))    # Output: 123
print(int("-456"))   # Output: -456
print(int("  789 ")) # Output: 789 (whitespace is ignored)
 
# These don't work
# print(int("12.5"))   # Error: ValueError: invalid literal for int()
# print(int("hello"))  # Error: ValueError: invalid literal for int()
# print(int("12 34"))  # Error: ValueError: invalid literal for int()

Vamos aprender a tratar esses erros de forma adequada no Capítulo 27, quando cobrirmos tratamento de exceções. Por enquanto, apenas saiba que é preciso garantir que suas strings contenham representações válidas de inteiros antes de convertê-las.

Convertendo booleanos para inteiros:

Booleanos podem ser convertidos para inteiros, onde True vira 1 e False vira 0:

python
# bool_to_int.py
print(int(True))   # Output: 1
print(int(False))  # Output: 0
 
# This is sometimes useful in calculations
is_premium = True
is_student = False
 
# Calculate discount (10% for premium, 5% for students)
discount = int(is_premium) * 0.10 + int(is_student) * 0.05
print("Discount:", discount)  # Output: Discount: 0.1

No entanto, usar booleanos diretamente em contas geralmente é desencorajado porque deixa o código menos legível. Vamos falar mais sobre isso no Capítulo 7.

3.7.3) Convertendo para Float com float()

A função float() converte um valor para número de ponto flutuante:

Convertendo inteiros para floats:

python
# int_to_float.py
x = float(42)
y = float(-17)
z = float(0)
 
print(x, type(x))  # Output: 42.0 <class 'float'>
print(y, type(y))  # Output: -17.0 <class 'float'>
print(z, type(z))  # Output: 0.0 <class 'float'>

Convertendo strings para floats:

python
# string_to_float.py
# Convert string containing decimal number
price_str = "19.99"
price_float = float(price_str)
 
print(price_str, type(price_str))    # Output: 19.99 <class 'str'>
print(price_float, type(price_float))  # Output: 19.99 <class 'float'>
 
# Strings without decimal points work too
x = float("42")
print(x, type(x))  # Output: 42.0 <class 'float'>
 
# Scientific notation strings work
big = float("1.5e10")
print(big)  # Output: 15000000000.0

Conversões inválidas:

Assim como int(), float() gera ValueError para strings inválidas:

python
# invalid_float_conversion.py
# These work
print(float("3.14"))      # Output: 3.14
print(float("  2.5  "))   # Output: 2.5 (whitespace ignored)
print(float("-0.5"))      # Output: -0.5
print(float("inf"))       # Output: inf (infinity)
 
# These don't work
# print(float("hello"))   # Error: ValueError
# print(float("1.2.3"))   # Error: ValueError

Convertendo booleanos para floats:

python
# bool_to_float.py
print(float(True))   # Output: 1.0
print(float(False))  # Output: 0.0

3.7.4) Convertendo para String com str()

A função str() converte qualquer valor para sua representação em string:

Convertendo números para strings:

python
# number_to_string.py
# Convert integer
age = 25
age_str = str(age)
print(age_str, type(age_str))  # Output: 25 <class 'str'>
 
# Convert float
price = 19.99
price_str = str(price)
print(price_str, type(price_str))  # Output: 19.99 <class 'str'>
 
# Now we can concatenate with other strings
message = "The price is $" + price_str
print(message)  # Output: The price is $19.99

Isso é particularmente útil na construção de mensagens:

python
# building_messages.py
name = "Alice"
age = 25
height = 5.6
 
# Without str(), this would cause an error
# message = "Name: " + name + ", Age: " + age  # Error!
 
# With str(), it works
message = "Name: " + name + ", Age: " + str(age) + ", Height: " + str(height)
print(message)  # Output: Name: Alice, Age: 25, Height: 5.6

Convertendo booleanos para strings:

python
# bool_to_string.py
is_valid = True
is_error = False
 
print(str(is_valid))  # Output: True
print(str(is_error))  # Output: False
 
# Useful in messages
status = "Status: " + str(is_valid)
print(status)  # Output: Status: True

Convertendo None para string:

python
# none_to_string.py
value = None
value_str = str(value)
print(value_str)        # Output: None
print(type(value_str))  # Output: <class 'str'>
 
# The string "None" is different from the value None
print(value is None)      # Output: True
print(value_str is None)  # Output: False
print(value_str == "None")  # Output: True

3.7.5) Padrões de Conversão na Prática

Aqui está um exemplo completo mostrando padrões comuns de conversão:

python
# conversion_patterns.py
# Get user input (always strings)
name = input("Enter your name: ")
age_str = input("Enter your age: ")
height_str = input("Enter your height in feet: ")
 
# Convert to appropriate types
age = int(age_str)
height = float(height_str)
 
# Perform calculations
age_in_months = age * 12
height_in_inches = height * 12
 
# Convert back to strings for output
print("Hello, " + name + "!")
print("You are " + str(age_in_months) + " months old.")
print("Your height is " + str(height_in_inches) + " inches.")
 
# Alternative: use multiple arguments to print() (no conversion needed)
print("Hello,", name + "!")
print("You are", age_in_months, "months old.")
print("Your height is", height_in_inches, "inches.")
 
# When user enters "Alice", "25", and "5.5":
# Output: Hello, Alice!
# Output: You are 300 months old.
# Output: Your height is 66.0 inches.
# Output: Hello, Alice!
# Output: You are 300 months old.
# Output: Your height is 66.0 inches.

Perceba como print() com múltiplos argumentos (separados por vírgulas) converte valores automaticamente para string e adiciona espaços entre eles. Isso muitas vezes é mais conveniente do que conversão manual e concatenação de strings.

3.7.6) Diagrama de Fluxo de Conversão

Aqui está uma representação visual de conversões comuns de tipos:

float

int truncates

str

str

int

float

str

int

float

int

float

str

bool

Pontos-chave sobre conversões:

  • int → float: sempre seguro, adiciona .0
  • float → int: trunca a parte decimal (não arredonda)
  • Qualquer tipo → str: sempre seguro, converte para representação textual
  • str → int/float: só funciona se a string representar um número válido
  • bool → int/float: True vira 1/1.0, False vira 0/0.0

3.7.7) Erros Comuns de Conversão

Aqui vão alguns erros comuns que iniciantes cometem com conversão de tipos:

Erro 1: Esquecer de converter a entrada do usuário

python
# conversion_mistake1.py
# Wrong: trying to do math with string
age = input("Enter your age: ")
# next_year = age + 1  # Error: TypeError
 
# Right: convert first
age = int(input("Enter your age: "))
next_year = age + 1
print("Next year:", next_year)

Erro 2: Converter quando não é necessário

python
# conversion_mistake2.py
# Unnecessary: print() handles conversion automatically
age = 25
print("Age:", age)  # This works fine
 
# No need for:
print("Age:", str(age))  # Unnecessary str() conversion

Erro 3: Tentar converter strings inválidas

python
# conversion_mistake3.py
# This will crash if user enters non-numeric input
# age = int(input("Enter your age: "))  # Crashes on "twenty"
 
# We'll learn to handle this safely in Chapter 27

Erro 4: Esperar que int() arredonde

python
# conversion_mistake4.py
# Wrong expectation: int() truncates, doesn't round
x = int(3.7)
print(x)  # Output: 3 (not 4!)
 
# If you want rounding, use round()
x = round(3.7)
print(x)  # Output: 4

3.8) Obtendo Representações em String com str() e repr()

3.8.1) A Diferença Entre str() e repr()

O Python fornece duas formas de obter uma representação em string de um objeto: str() e repr(). Embora pareçam semelhantes, elas têm propósitos diferentes:

  • str(): cria uma representação em string “bonita”, legível para humanos
  • repr(): cria uma representação em string “oficial”, não ambígua, voltada para desenvolvedores

Para tipos simples como números, elas geralmente são iguais, mas para outros tipos podem ser bem diferentes:

python
# str_vs_repr.py
# For numbers, they're usually the same
x = 42
print(str(x))   # Output: 42
print(repr(x))  # Output: 42
 
# For strings, they differ
text = "Hello"
print(str(text))   # Output: Hello
print(repr(text))  # Output: 'Hello' (includes quotes!)
 
# For strings with special characters, repr() shows escape sequences
message = "Hello\nWorld"
print(str(message))   # Output: Hello
                      #         World (newline is interpreted)
print(repr(message))  # Output: 'Hello\nWorld' (shows the \n literally)

3.8.2) Quando Usar str()

Use str() quando quiser uma representação legível para o usuário final:

python
# using_str.py
price = 19.99
quantity = 3
 
# Create user-friendly messages
message = "Total: $" + str(price * quantity)
print(message)  # Output: Total: $59.97
 
# str() is what print() uses automatically
print("Total: $", price * quantity)  # Output: Total: $ 59.97

A função str() é projetada para produzir uma saída que faça sentido para humanos, mesmo que perca um pouco de precisão técnica. Quando você chama print(), o Python chama str() automaticamente para os valores passados.

3.8.3) Quando Usar repr()

Use repr() quando precisar de uma representação não ambígua, tipicamente para depuração:

python
# using_repr.py
# Debugging: see exactly what's in a variable
text = "Hello\nWorld"
print("Debug info:", repr(text))  # Output: Debug info: 'Hello\nWorld'
 
# Compare two similar-looking strings
str1 = "42"
str2 = "42 "  # Has trailing space
 
print(str1)       # Output: 42
print(str2)       # Output: 42  (space not obvious)
print(repr(str1)) # Output: '42'
print(repr(str2)) # Output: '42 ' (space is visible!)

A função repr() é projetada para mostrar exatamente o que o Python vê, incluindo detalhes que podem não ser visíveis na saída normal. Isso a torna inestimável na depuração.

3.8.4) O Objetivo de repr(): Representações Recriáveis

Idealmente, repr() deveria produzir uma string que, se você passasse ao interpretador do Python, recriaria o objeto original. Para tipos básicos, isso funciona:

python
# repr_recreate.py
# For numbers
x = 42
x_repr = repr(x)
print(x_repr)  # Output: 42
 
# You could use this to recreate x
x_recreated = eval(x_repr)  # eval() evaluates a string as Python code
print(x_recreated)  # Output: 42
 
# For strings
text = "Hello"
text_repr = repr(text)
print(text_repr)  # Output: 'Hello'
 
# This could recreate the string
text_recreated = eval(text_repr)
print(text_recreated)  # Output: Hello

Nota importante: A função eval() avalia uma string como código Python. Mencionamos isso aqui para explicar o propósito de repr(), mas nunca use eval() em entrada não confiável—é um risco de segurança. Vamos discutir alternativas mais seguras em capítulos posteriores.

3.8.5) Exemplos Práticos de str() e repr()

Exemplo 1: Depurando problemas com strings

python
# debugging_strings.py
# User input might have unexpected whitespace
user_input = "  Alice  "
 
print("User entered:", user_input)         # Output: User entered:   Alice  
print("Debug view:", repr(user_input))     # Output: Debug view: '  Alice  '
 
# Now the extra spaces are obvious!
cleaned = user_input.strip()  # Remove leading/trailing whitespace
print("Cleaned:", repr(cleaned))  # Output: Cleaned: 'Alice'

Exemplo 2: Comparando tipos diferentes

python
# comparing_types.py
# These look similar but are different
num = 42
text = "42"
 
print("Number:", num)       # Output: Number: 42
print("Text:", text)        # Output: Text: 42
 
print("Number repr:", repr(num))   # Output: Number repr: 42
print("Text repr:", repr(text))    # Output: Text repr: '42'
 
# repr() makes the difference clear
print("Are they equal?", num == text)  # Output: Are they equal? False

3.8.6) str() e repr() com Outros Tipos

Vamos ver como str() e repr() funcionam com os tipos que aprendemos:

python
# str_repr_types.py
# Integers
x = 42
print("int str:", str(x))    # Output: int str: 42
print("int repr:", repr(x))  # Output: int repr: 42
 
# Floats
y = 3.14159
print("float str:", str(y))   # Output: float str: 3.14159
print("float repr:", repr(y)) # Output: float repr: 3.14159
 
# Booleans
b = True
print("bool str:", str(b))   # Output: bool str: True
print("bool repr:", repr(b)) # Output: bool repr: True
 
# None
n = None
print("None str:", str(n))   # Output: None str: None
print("None repr:", repr(n)) # Output: None repr: None
 
# Strings (where they differ most)
s = "Hello\nWorld"
print("string str:", str(s))   # Output: string str: Hello
                                #                     World
print("string repr:", repr(s)) # Output: string repr: 'Hello\nWorld'

3.8.7) Pontos-Chave

Use str() quando:

  • Criar saída para usuários finais
  • Montar mensagens voltadas para o usuário
  • Formatar dados para exibição
  • Você quer uma saída legível e amigável

Use repr() quando:

  • Estiver depurando código
  • Registrando informações técnicas (logs)
  • Precisar ver exatamente o que há em uma variável
  • Quiser representações não ambíguas

Lembre-se:

  • print() usa str() automaticamente em seus argumentos
  • Para a maioria dos tipos básicos, str() e repr() dão resultados semelhantes
  • Para strings, repr() inclui aspas e mostra sequências de escape
  • repr() é projetada para ser não ambígua e (idealmente) recriável

Resumo do Capítulo

Neste capítulo, você aprendeu os conceitos fundamentais de variáveis e tipos de dados em Python. Vamos recapitular os pontos principais:

Variáveis:

  • Variáveis são nomes que se referem a valores na memória
  • Criadas usando atribuição: variable_name = value
  • Podem ser reatribuídas a novos valores a qualquer momento
  • Devem seguir regras de nomeação e deveriam seguir convenções
  • Use nomes descritivos para tornar o código autoexplicativo

Tipos de Dados:

  • Todo valor em Python tem um tipo
  • Use type() para verificar o tipo de um valor
  • O Python tem tipagem dinâmica—variáveis podem referir-se a tipos diferentes em momentos diferentes
  • Tipos diferentes suportam operações diferentes

Os Tipos Básicos:

  • int: números inteiros (positivos, negativos ou zero), tamanho arbitrário
  • float: números com ponto decimal, podem ter limitações de precisão
  • str: texto entre aspas (simples ou duplas)
  • bool: valores lógicos True ou False
  • None: valor especial que representa ausência de valor

Conversão de Tipos:

  • int(): converte para inteiro (trunca floats, interpreta strings)
  • float(): converte para número de ponto flutuante
  • str(): converte para string (sempre funciona)
  • Conversões podem falhar com entrada inválida (geram ValueError)

Representações em String:

  • str(): representação legível para usuários finais
  • repr(): representação não ambígua para desenvolvedores/depuração
  • print() usa str() automaticamente

Esses conceitos formam a base para todo o resto em Python. Todo programa que você escrever vai usar variáveis para armazenar dados, e entender tipos de dados ajuda você a prever quais operações vão funcionar e quais erros podem ocorrer.

No próximo capítulo, vamos construir sobre essa base explorando como trabalhar com números em detalhes, incluindo operações aritméticas, precedência de operadores e padrões numéricos comuns. Você vai aprender a realizar cálculos, usar funções matemáticas e lidar com as peculiaridades da aritmética de ponto flutuante.

© 2025. Primesoft Co., Ltd.
support@primesoft.ai