Módulos
Conforme um programa cresce, manter tudo em um único arquivo vira um problema. Módulos são a forma de dividir código em partes organizadas e reutilizáveis - e também como você usa código que outras pessoas já escreveram.
O que é um módulo
Seção intitulada “O que é um módulo”Todo arquivo .py é, por definição, um módulo. Se você tem um arquivo calculadora.py, ele já pode ser importado por outro arquivo como o módulo calculadora.
- Módulo: um único arquivo
.py - Pacote: uma pasta com vários módulos relacionados (visto na próxima seção)
- Biblioteca: um conjunto de módulos/pacotes distribuído para reuso (a biblioteca padrão do Python, ou algo instalado via
pip)
Importando módulos
Seção intitulada “Importando módulos”A forma mais simples importa o módulo inteiro, e você acessa o conteúdo com modulo.nome:
import math
print(math.sqrt(16)) # 4.0print(math.pi) # 3.141592653589793Quando você só precisa de um ou outro item, from ... import ... traz esse item direto para o escopo atual, sem precisar prefixar com o nome do módulo:
from math import sqrt, pi
print(sqrt(16))print(pi)Para módulos com nome longo (ou para evitar conflito com outro nome já usado), um alias com as ajuda:
import datetime as dt
agora = dt.datetime.now()Evite from modulo import *: isso importa tudo que o módulo expõe para o escopo atual, sem deixar claro de onde cada nome veio - dificulta a leitura e pode sobrescrever nomes que você já tinha.
A biblioteca padrão do Python já traz módulos prontos para tarefas comuns, sem precisar instalar nada extra:
import randomimport datetimeimport osimport sys
print(random.randint(1, 10)) # número aleatório entre 1 e 10print(datetime.date.today()) # data de hojeprint(os.getcwd()) # diretório atualprint(sys.version) # versão do Python em usoUm detalhe sobre importação: o Python carrega e executa um módulo uma única vez por execução do programa, mesmo que ele seja importado em vários arquivos diferentes. Da segunda importação em diante, o Python reaproveita o módulo já carregado em cache (em sys.modules), em vez de executar o arquivo de novo.
Criando módulos próprios
Seção intitulada “Criando módulos próprios”Organizar código em módulos separados é só uma questão de criar arquivos .py e importar um no outro:
def soma(a: float, b: float) -> float: return a + b
def subtrai(a: float, b: float) -> float: return a - bfrom operacoes import soma, subtrai
print(soma(5, 3)) # 8print(subtrai(5, 3)) # 2if __name__ == "__main__":
Seção intitulada “if __name__ == "__main__":”Toda vez que um módulo é executado diretamente (python arquivo.py), o Python define a variável especial __name__ como "__main__" nesse arquivo. Quando o mesmo arquivo é importado por outro, __name__ recebe o nome do módulo em vez disso.
Esse comportamento permite escrever um arquivo que funciona tanto como script quanto como módulo importável:
def soma(a: float, b: float) -> float: return a + b
if __name__ == "__main__": # só executa quando rodar "python operacoes.py" diretamente print(soma(2, 2))Se outro arquivo fizer import operacoes, o bloco dentro do if não executa - só o def é processado. É por isso que esse padrão aparece em praticamente todo script Python.
Pacotes básicos
Seção intitulada “Pacotes básicos”Um pacote é uma pasta com vários módulos relacionados, mais um arquivo especial __init__.py marcando essa pasta como importável:
meu_projeto/├── calculos/│ ├── __init__.py│ ├── basicos.py│ └── avancados.py└── main.pyfrom calculos.basicos import somafrom calculos import avancadosO __init__.py pode ficar vazio - ele só sinaliza para o Python que aquela pasta é um pacote. (Desde a PEP 420, Python 3.3+, também existem “pacotes de namespace” implícitos, que dispensam esse arquivo em casos mais avançados - mas criar o __init__.py continua sendo a prática mais simples e previsível para projetos comuns.)
Imports dentro do próprio pacote podem ser absolutos (caminho completo, a partir da raiz do projeto) ou relativos (from . import avancados, relativo à posição do próprio módulo). Prefira imports absolutos: são mais fáceis de ler e não quebram se você mover um arquivo dentro do pacote.