Argumentos Mutáveis de Função

O Python possui uma variedade de tipos de dados, alguns dos quais podem ser modificados após a sua criação e outros não. Quando falamos de tipos que podem ser alterados, referimo-nos a eles como tipos "mutáveis". Em contraste, aqueles que não podem ser alterados são chamados de tipos "imutáveis".

Tipos Mutáveis

Os tipos mutáveis mais comuns são lists, dicts e sets. Aqui está um exemplo de uma lista:

fruits = ['apple', 'banana', 'cherry']
print(fruits, type(fruits))  # ['apple', 'banana', 'cherry'] <class 'list'>

Com uma list, pode alterar os seus elementos, adicionar novos ou remover existentes:

fruits[1] = 'blueberry'       # Muda 'banana' para 'blueberry'
fruits.append('dragonfruit')  # Adiciona 'dragonfruit' ao fim da lista
print(fruits)                 # ['apple', 'blueberry', 'cherry', 'dragonfruit']

Tipos Imutáveis

Por outro lado, exemplos de tipos imutáveis são ints, floats, strings e tuples. Uma vez criados, não pode alterar o seu conteúdo. Aqui está um exemplo de uma string:

message = 'hello'
print(message, type(message))  # hello <class 'str'>

Se tentar alterar parte da string, o Python não o permitirá:

message[0] = 'H'  # Tentar mudar 'h' para 'H' dará um TypeError
Como é que int é imutável? Não podemos mudar o valor com += ou -=?

Quando falamos sobre mutabilidade no Python, referimo-nos à capacidade de o valor real armazenado na memória poder ser alterado. Por exemplo, quando temos uma lista, podemos alterar um item nessa lista, e continua a ser a mesma lista na memória.

Inteiros no Python são imutáveis. Isto significa que o valor na memória não pode ser alterado. Se tivermos um inteiro, a = 5, e realizarmos uma operação como a += 2, pode parecer que alterámos a. No entanto, o que o Python realmente fez foi criar um novo objeto na memória com o valor de 7 e atualizar a para apontar para esse novo objeto. O 5 original não foi alterado na memória — é por isso que ints são considerados imutáveis.

a = 5
print(id(a))  # Isto imprime a localização na memória de a. Vamos supor que é 1001

a += 2
print(a)      # Isto imprime 7
print(id(a))  # Isto imprimirá uma localização de memória diferente, digamos 1002

A função id em Python retorna a identidade de um objeto, que é única e constante durante a vida útil do objeto. Portanto, quando vemos que a identidade de a mudou após a operação a += 2, é um sinal claro de que a agora aponta para um novo objeto na memória. O inteiro original 5 não foi alterado, confirmando que os inteiros são realmente imutáveis em Python.

Argumentos Mutáveis em Funções

Quando passamos um objeto mutável (como uma lista) para uma função, o Python fornece à função uma referência a esse objeto. Isto significa que, se a função modificar o objeto mutável, essa modificação também será visível fora da função.

Vamos utilizar uma função que recebe uma lista e adiciona um elemento a ela:

def add_item(my_list):
    my_list.append('added item')  # Adiciona um novo item à lista

shopping_list = ['apples', 'bananas', 'cherries']
print(shopping_list)  # Imprime: ['apples', 'bananas', 'cherries']

# Agora usamos a função para adicionar um item à nossa lista de compras
add_item(shopping_list)
print(shopping_list)  # Imprime: ['apples', 'bananas', 'cherries', 'added item']

Como pode ver, quando imprimimos shopping_list após chamar a função add_item, a lista tinha um novo item. Isto aconteceu mesmo sem modificarmos diretamente shopping_list fora da função.

No entanto, é essencial compreender que, se atribuir um novo valor ao objeto mutável inteiro dentro da função, isso não afetará o objeto original. Isto porque está a atribuir uma nova referência à variável local da função, não modificando o objeto original. Vamos ver um exemplo disto:

def change_list(my_list):
    my_list = ['entirely', 'new', 'list']  # Isto não afetará a lista original

shopping_list = ['apples', 'bananas', 'cherries']
change_list(shopping_list)
print(shopping_list)  # Ainda imprime: ['apples', 'bananas', 'cherries']

Embora tenhamos chamado a função change_list com shopping_list como argumento, o conteúdo de shopping_list não mudou. Isto porque, dentro da função, my_list recebeu uma nova referência (para uma lista completamente nova), enquanto a referência de shopping_list permaneceu intocada.

A principal conclusão aqui é: quando passa um objeto mutável para uma função em Python, lembre-se de que, se a função alterar o objeto (como adicionar um item a uma lista), a alteração é permanente e visível fora da função. Porém, se atribuir um novo valor ao objeto inteiro dentro da função, isso não afetará o objeto original.

To check your solution you need to sign in

Sign in to continue

Sign in to your account

By continuing, you agree to our Terms of Service and Privacy Policy.