Módulos e a biblioteca padrão
Python vem com uma enorme coleção de ferramentas prontas para uso: aleatoriedade, matemática, datas, caminhos de arquivos e muito mais. Essas ferramentas vivem em módulos, e você as traz para o seu código com import. Você já usou import json no capítulo anterior. Este capítulo cobre imports completamente e apresenta as partes mais úteis da biblioteca padrão.
Importando módulos
O import mais simples traz um módulo inteiro e permite que você use seu conteúdo com notação de ponto. Você também pode importar nomes específicos de um módulo para usá-los diretamente sem o prefixo. Apelidos encurtam nomes longos.
import math
math.sqrt(16) # 4.0
math.pi # 3.141592653589793
math.floor(3.9) # 3
math.ceil(3.1) # 4Importe nomes específicos de um módulo para que você possa usá-los diretamente:
from math import sqrt, pi
sqrt(16) # 4.0 (sem necessidade do prefixo "math.")
pi # 3.141592653589793Dê a um módulo ou nome um apelido para encurtá-lo:
import math as m
m.sqrt(16) # 4.0
from math import sqrt as square_root
square_root(25) # 5.0Apelidos são comuns com bibliotecas populares de terceiros (import numpy as np, import pandas as pd). Para módulos da biblioteca padrão, prefira usar o nome completo; isso torna o código mais fácil de ler.
random
O módulo random gera números aleatórios e faz escolhas aleatórias. Use-o para jogos, simulações, amostragem aleatória e qualquer outra coisa que precise de imprevisibilidade. Definir uma seed torna os resultados reproduzíveis: a mesma seed produz a mesma sequência toda vez.
import random
random.random() # float entre 0 e 1 (exclusivo)
random.randint(1, 10) # inteiro de 1 a 10 (ambos inclusivos)
random.uniform(1.0, 10.0) # float entre 1.0 e 10.0
colours = ["red", "green", "blue"]
random.choice(colours) # escolhe um item
random.choices(colours, k=3) # escolhe k itens (com reposição)
random.sample(colours, k=2) # escolhe k itens (sem reposição)
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers) # embaralha no lugar, retorna NonePara resultados reproduzíveis (úteis em testes e ciência de dados), defina uma seed antes de gerar:
random.seed(42)
random.randint(1, 100) # sempre o mesmo valor para seed 42A mesma seed produz a mesma sequência toda vez, em qualquer máquina.
math
O módulo math adiciona operações matemáticas mais avançadas além dos operadores aritméticos básicos. Raízes quadradas, potências, logaritmos, trigonometria e valores especiais como pi e infinito estão todos aqui.
import math
math.sqrt(25) # 5.0
math.pow(2, 10) # 1024.0 (igual a 2 ** 10 mas sempre retorna float)
math.log(100, 10) # 2.0 (log base 10)
math.log(math.e) # 1.0 (log natural)
math.sin(math.pi / 2) # 1.0
math.cos(0) # 1.0
math.ceil(3.2) # 4
math.floor(3.9) # 3
math.trunc(3.9) # 3 (igual a int() para positivos)
math.inf # infinito
math.isnan(float("nan")) # True
math.isinf(math.inf) # Truedatetime
O módulo datetime lida com datas e horários. datetime.now() retorna a data e hora atuais. strftime() formata como string. strptime() interpreta uma string como datetime. timedelta representa uma duração que você pode adicionar ou subtrair.
from datetime import datetime, date, timedelta
now = datetime.now() # data e hora atuais
today = date.today() # apenas data atual
print(now.year, now.month, now.day)
print(now.hour, now.minute, now.second)
# Formatação
print(now.strftime("%Y-%m-%d")) # "2024-01-15"
print(now.strftime("%d %B %Y, %H:%M")) # "15 January 2024, 09:42"
# Parsing
deadline = datetime.strptime("2024-12-31", "%Y-%m-%d")
# Aritmética
tomorrow = today + timedelta(days=1)
next_week = today + timedelta(weeks=1)
diff = deadline - now
print(f"{diff.days} days until deadline")Códigos comuns do strftime:
| Código | Significado | Exemplo |
|---|---|---|
%Y | Ano com 4 dígitos | 2024 |
%m | Mês (com zero à esquerda) | 01 |
%d | Dia (com zero à esquerda) | 15 |
%H | Hora (24h) | 09 |
%M | Minuto | 42 |
%B | Nome completo do mês | January |
os e pathlib
pathlib é a forma moderna de trabalhar com caminhos de arquivos. Objetos Path permitem construir, inspecionar e navegar por caminhos usando o operador /. os dá acesso a variáveis de ambiente e operações de baixo nível do SO. Prefira pathlib para código novo.
from pathlib import Path
p = Path("data/reports")
p.exists() # True se o caminho existir
p.is_dir() # True se for um diretório
p.is_file() # True se for um arquivo
p.mkdir(parents=True, exist_ok=True) # cria diretórios
for f in p.glob("*.csv"): # todos os arquivos CSV no diretório
print(f.name) # apenas o nome do arquivo
report = p / "report_jan.csv" # operador / junta caminhos
report.stem # "report_jan" (nome sem extensão)
report.suffix # ".csv"
report.parent # Path("data/reports")
content = report.read_text() # lê o conteúdo do arquivo diretamente
report.write_text("new content\n") # escreve diretamentePara o módulo os:
import os
os.getcwd() # diretório de trabalho atual
os.listdir(".") # lista o conteúdo do diretório
os.path.exists("data.txt") # True se o caminho existir
os.path.join("data", "file.txt") # "data/file.txt" (multiplataforma)
os.environ.get("HOME") # lê uma variável de ambientePrefira pathlib para código novo. Use os quando precisar de variáveis de ambiente ou ao trabalhar com APIs mais antigas que esperam strings.
timeit
timeit mede quanto tempo o código leva para rodar. É útil quando você quer comparar duas abordagens e escolher a mais rápida. Execute o código muitas vezes para obter uma medição estável.
import timeit
# Mede uma única instrução
timeit.timeit("sum(range(1000))", number=10000)
# Mede um bloco mais complexo
setup = "data = list(range(1000))"
code = "[x * 2 for x in data]"
time = timeit.timeit(code, setup=setup, number=10000)
print(f"{time:.4f} seconds for 10,000 runs")number é quantas vezes repetir. Mais repetições resultam em uma medição mais estável.
string
O módulo string fornece constantes de string pré-construídas para letras, dígitos e pontuação. Útil quando você precisa verificar caracteres ou gerar strings aleatórias a partir de um alfabeto específico.
import string
string.ascii_lowercase # "abcdefghijklmnopqrstuvwxyz"
string.ascii_uppercase # "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
string.ascii_letters # ambos combinados
string.digits # "0123456789"
string.punctuation # todos os caracteres de pontuaçãoÚtil quando você precisa verificar caracteres ou gerar strings aleatórias:
import string, random
chars = string.ascii_letters + string.digits
password = "".join(random.choices(chars, k=12))Criando seus próprios módulos
Qualquer arquivo Python é um módulo. Para usá-lo a partir de outro arquivo, importe-o pelo nome do arquivo (sem .py). Você pode importar o módulo inteiro e usar seu conteúdo com notação de ponto, ou importar nomes específicos diretamente.
# utils.py
def clamp(value, lo, hi):
return max(lo, min(value, hi))
PI = 3.14159# main.py
import utils
utils.clamp(150, 0, 100) # 100
utils.PI # 3.14159
from utils import clamp
clamp(50, 0, 100) # 50O Python encontra o módulo procurando no mesmo diretório do arquivo que está importando (e em alguns outros lugares). Para projetos maiores, módulos são organizados em pacotes: diretórios com um arquivo __init__.py.
__name__ == "__main__"
Quando o Python executa um arquivo diretamente, __name__ é definido como "__main__". Quando o mesmo arquivo é importado como módulo, __name__ é o nome do módulo. Esse padrão permite escrever código que roda quando você executa o arquivo diretamente, mas é ignorado quando o arquivo é importado por outro módulo.
# utils.py
def clamp(value, lo, hi):
return max(lo, min(value, hi))
if __name__ == "__main__":
# isto só roda quando você faz: python utils.py
# não quando você faz: import utils
print(clamp(150, 0, 100)) # 100Esse é um padrão padrão para qualquer módulo que também seja útil como script autônomo.
Destaques da biblioteca padrão
Mais alguns módulos que vale a pena conhecer. Cada um resolve um problema comum que daria muito trabalho para implementar por conta própria.
collections: tipos de containers especializados:
from collections import Counter, defaultdict, deque
Counter(["a", "b", "a", "c", "a"]) # Counter({'a': 3, 'b': 1, 'c': 1})
defaultdict(list) # dict que cria chaves ausentes automaticamente
deque([1, 2, 3], maxlen=5) # append/pop rápido nas duas extremidadesitertools: ferramentas para trabalhar com iteráveis:
import itertools
list(itertools.chain([1, 2], [3, 4])) # [1, 2, 3, 4]
list(itertools.islice(range(100), 5)) # [0, 1, 2, 3, 4]
list(itertools.combinations([1, 2, 3], 2)) # [(1, 2), (1, 3), (2, 3)]
list(itertools.product([0, 1], repeat=2)) # [(0,0), (0,1), (1,0), (1,1)]sys: acesso ao interpretador Python:
import sys
sys.argv # lista de argumentos de linha de comando
sys.exit(1) # sai com um código de status
sys.version # string da versão do PythonPacotes de terceiros: além da biblioteca padrão, o pip instala pacotes da comunidade:
pip install requests # biblioteca HTTP
pip install pandas # manipulação de dados
pip install numpy # computação numéricaPacotes de terceiros estão fora do escopo deste guia, mas o padrão é sempre o mesmo: pip install, depois import.
Na prática
Combinando random, string e datetime para gerar IDs únicos de jogos com timestamps:
import random
import string
from datetime import datetime
def generate_game_id(length: int = 8) -> str:
chars = string.ascii_uppercase + string.digits
return "".join(random.choices(chars, k=length))
def timestamp() -> str:
return datetime.now().strftime("%Y-%m-%d %H:%M:%S")
game_id = generate_game_id()
print(f"[{timestamp()}] Starting game {game_id}")
scores = [random.randint(50, 100) for _ in range(5)]
print(f"Round scores: {scores}")
print(f"Best: {max(scores)}")
