Mutável e Imutável em Python

Mutável e Imutável em Python

Este artigo explica mutável e imutável em Python.

YouTube Video

Mutável e Imutável em Python

"Mutável" e "imutável" referem-se à mutabilidade de um objeto. Entender isso ajuda a evitar bugs inesperados e a gerenciar memória de forma eficiente.

O que é Mutável?

Objetos mutáveis podem ter seu estado interno alterado após a criação.

Principais Tipos de Dados Mutáveis

  • list
  • dict
  • set
  • Classes definidas pelo usuário (se seus atributos puderem ser modificados)

Exemplo: Modificando uma Lista

1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers)  # [100, 2, 3]

Uma lista é um objeto mutável, e seus elementos podem ser modificados livremente.

O que é Imutável?

Objetos imutáveis não podem ser alterados após serem criados. Tentar modificá-los resulta na criação de um novo objeto.

Principais Tipos de Dados Imutáveis

  • int
  • float
  • str
  • tuple
  • bool
  • frozenset

Exemplo: Modificando uma String

1text = "hello"
2# text[0] = "H"  # TypeError: 'str' object does not support item assignment
3
4text = "H" + text[1:]  # Creates a new string
5print(text)  # "Hello"

Strings são imutáveis, então você não pode modificá-las parcialmente.

Comparação entre Mutável e Imutável

 1# Mutable example
 2a = [1, 2, 3]
 3b = a
 4b[0] = 100
 5print(a)  # [100, 2, 3] -> a is also changed
 6
 7# Immutable example
 8x = 10
 9y = x
10y = 20
11print(x)  # 10 -> x is unchanged

Como você pode ver neste exemplo, objetos mutáveis são compartilhados por referência, por isso podem afetar outras variáveis. Por outro lado, objetos imutáveis criam novas instâncias ao serem reassociados, deixando o valor original inalterado.

Inspecionando o Comportamento Interno Usando id()

Em Python, você pode usar a função id() para verificar o ID de um objeto. O ID do objeto é semelhante a um endereço de memória.

 1# Immutable int behavior
 2a = 10
 3print(id(a))  # e.g., 140715920176592
 4a += 1
 5print(id(a))  # e.g., 140715920176624 -> ID has changed
 6
 7# Mutable list behavior
 8b = [1, 2, 3]
 9print(id(b))  # e.g., 2819127951552
10b.append(4)
11print(id(b))  # Same ID -> only the content has changed

Conforme mostrado, um novo objeto é criado para tipos imutáveis, enquanto os tipos mutáveis são modificados no local.

Funções e Cuidado com Objetos Mutáveis e Imutáveis

Ao passar um objeto mutável para uma função, os dados originais podem ser modificados.

Exemplo: Uma Função que Modifica uma Lista

1def modify_list(lst):
2    lst.append(100)
3
4my_list = [1, 2, 3]
5modify_list(my_list)
6print(my_list)  # [1, 2, 3, 100]

Exemplo: Uma Função que Modifica um Número

Por outro lado, tentar modificar um objeto imutável resulta na criação de um novo objeto.

1def modify_number(n):
2    n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number)  # 5 -> unchanged

Considerações Práticas

Evite Usar Objetos Mutáveis como Argumentos Padrão

 1# Bad example
 2def add_item(item, container=[]):
 3    container.append(item)
 4    return container
 5
 6print(add_item(1))  # [1]
 7print(add_item(2))  # [1, 2] -> unintended behavior
 8
 9# Good example
10def add_item(item, container=None):
11    if container is None:
12        container = []
13    container.append(item)
14    return container
15
16print(add_item(1))  # [1]
17print(add_item(2))  # [2]

Como os argumentos padrão são avaliados apenas uma vez na definição da função, usar objetos mutáveis pode levar a efeitos colaterais inesperados.

  • No primeiro exemplo, o mesmo objeto de lista é usado toda vez que add_item é chamado. Ao chamar add_item(2) pela segunda vez, o 1 adicionado anteriormente ainda está na lista, resultando em [1, 2].
  • No exemplo aprimorado, None é usado como valor padrão, e uma nova lista é criada dentro da função se o argumento for None. Isso garante que uma nova lista seja criada cada vez que a função é chamada, assim os resultados anteriores não afetam as chamadas subsequentes.

Evite usar objetos mutáveis como listas ou dicionários como argumentos padrão; em vez disso, use None e inicialize-os dentro da função. Esta é uma prática fundamental e importante em Python.

Resumo

Para entender profundamente as variáveis e os tipos de dados em Python, é crucial compreender as diferenças entre mutáveis e imutáveis. Compreender essas características ajuda a evitar comportamentos indesejados no seu código e a escrever programas mais robustos e legíveis.

Você pode acompanhar o artigo acima usando o Visual Studio Code em nosso canal do YouTube. Por favor, confira também o canal do YouTube.

YouTube Video