Imutabilidade em Python

python
0 – Python
6 – Funcional
6.1 – Funcoes puras
6.2 – Imutabilidade (tuplas, frozenset, namedtuple)
6.3 – Funcoes de alta ordem (map, filter, reduce)
6.4 – Comprehensions (list, dict, set)
6.5 – Geradores (yield, generator expressions)
6.6 – Decorators (@)
6.7 – Closures
6.8 – Funcoes lambda
LEGENDA
Nivel_1
Nivel_2
Nivel_3

Imutabilidade significa que um objeto não pode ser alterado após criado. Qualquer modificação gera um novo objeto na memória. Primeiramente, isso evita efeitos colaterais indesejados em funções. Por exemplo, tuplas são imutáveis, enquanto listas são mutáveis. Além disso, frozenset e namedtuple também seguem esse princípio. A voz passiva é usada aqui: “os dados originais são preservados para sempre”. Quando utilizar imutabilidade? Em chaves de dicionários e conjuntos. Também em programação funcional e dados compartilhados entre threads. Python oferece estruturas imutáveis nativas para esses casos. Vamos explorar tuplas, frozenset e namedtuple em detalhes. Três subtítulos guiarão você pelo mundo da imutabilidade. Ao final, você escolherá a estrutura certa para cada situação.

Tuplas: listas imutáveis

Tuplas são sequências imutáveis de elementos em Python. Você cria uma tupla com parênteses: (1, 2, 3). Quando usar tuplas? Em dados que não devem mudar. Por exemplo, coordenadas geográficas ou cores RGB. A voz passiva é aplicada: “os elementos são acessados por índice”. Exemplo de tuplas e suas características:

Tuplas são mais rápidas e consomem menos memória que listas. Use tuplas sempre que os dados forem fixos e imutáveis.

Frozenset: conjuntos imutáveis

Frozenset é a versão imutável de um set (conjunto). Ele suporta operações de conjunto sem alterar os dados. Quando usar frozenset? Como chave de dicionário. Também para armazenar dados únicos que não devem mudar. A voz passiva é aplicada: “os elementos são únicos e imutáveis”. Exemplo de frozenset:

Frozenset é ideal para conjuntos constantes e chaves de dicionário. Ele mantém todas as operações úteis dos sets sem a mutabilidade.

NamedTuple: tuplas com nomes de campos

NamedTuple combina imutabilidade de tupla com nomes de campos. Ela funciona como uma classe leve e imutável. Quando usar NamedTuple? Em estruturas de dados simples. Por exemplo, pontos, pessoas ou produtos imutáveis. A voz passiva é aplicada: “os campos são acessados por nome ou índice”. Exemplo de NamedTuple:

NamedTuple oferece a melhor experiência para dados imutáveis. A fórmula da escolha entre estruturas imutáveis: \(E = \begin{cases} \text{tupla} & \text{simples e sem nomes} \\ \text{frozenset} & \text{operações de conjunto} \\ \text{namedtuple} & \text{acesso por nome} \end{cases}\) Imutabilidade não é apenas uma restrição, é uma garantia. Use-a para tornar seu código mais seguro e previsível. Tuplas para sequências simples e rápidas. Frozenset para conjuntos únicos que servem como chaves. NamedTuple para objetos leves com campos nomeados. Seu código será mais robusto e fácil de entender.

Funções Puras em Python

python
0 – Python
6 – Funcional
6.1 – Funcoes puras
6.2 – Imutabilidade (tuplas, frozenset, namedtuple)
6.3 – Funcoes de alta ordem (map, filter, reduce)
6.4 – Comprehensions (list, dict, set)
6.5 – Geradores (yield, generator expressions)
6.6 – Decorators (@)
6.7 – Closures
6.8 – Funcoes lambda
LEGENDA
Nivel_1
Nivel_2
Nivel_3

Função pura é aquela que sempre produz a mesma saída para uma mesma entrada. Ela não modifica variáveis externas nem causa efeitos colaterais. Primeiramente, funções puras são previsíveis e fáceis de testar. Por exemplo, def soma(a, b): return a + b é pura. Além disso, elas não dependem de estado global ou I/O. A voz passiva é usada aqui: “os dados são transformados sem alteração externa”. Quando utilizar funções puras? Em operações matemáticas e transformações de dados. Também em funções de validação e cálculos repetitivos. Python permite escrever código funcional de forma natural. Vamos explorar características, vantagens e exemplos práticos. Três subtítulos guiarão você pelas funções puras. Ao final, você identificará e criará funções puras com confiança.

Características essenciais das funções puras

Função pura não tem efeitos colaterais observáveis. Ela não altera variáveis globais, arquivos ou bancos de dados. Também não modifica seus argumentos de entrada (imutabilidade). Quando usar essas características? Em código que precisa de confiabilidade. Por exemplo, sistemas financeiros ou de processamento crítico. A voz passiva é aplicada: “os argumentos são tratados como somente leitura”. Exemplo comparando funções puras e impuras:

Funções puras são transparentes e previsíveis. Funções impuras podem causar bugs difíceis de rastrear.

Vantagens e benefícios das funções puras

Funções puras são extremamente fáceis de testar unitariamente. Elas não dependem de contexto ou estado externo. Além disso, são seguras para execução paralela (sem locks). Quando usar essas vantagens? Em sistemas concorrentes e testes. Também em código que precisa ser reutilizado em diferentes contextos. A voz passiva é aplicada: “os testes podem ser escritos sem preparação complexa”. Exemplo demonstrando vantagens:

Funções puras simplificam testes, cache e paralelismo. Elas são a base para código robusto e escalável.

Identificando e transformando funções impuras

Nem toda função precisa ou deve ser pura. I/O, rede, banco de dados e aleatoriedade exigem impureza. Quando identificar uma função impura? Quando ela lê arquivos ou gera números. Também quando modifica estado global ou argumentos mutáveis. A voz passiva é aplicada: “a impureza é isolada nas bordas do sistema”. Exemplo de como transformar funções impuras em puras:

Isolando impurezas nas bordas do sistema, o núcleo fica puro. A fórmula da pureza de uma função pode ser expressa: \(P = \frac{\text{mesma saída para mesma entrada}}{\text{sem efeitos colaterais}}\) Funções puras não são bala de prata para tudo. Para I/O e interação com usuário, impureza é necessária. Porém, maximize funções puras no núcleo da sua lógica. Seu código será mais fácil de entender, testar e manter.