4
respostas

[Dúvida] Atributo privado ( _nome ) pode ser alterado na instancia

Gostaria de entender melhor, mesmo o atributo sendo privado ele poderá ser alterado diretamente pela instancia? existe alguma propriedade especifica que defina um modificador de acesso para que não seja permitido essa alteração diretamente pela instância

restaurante_praca = Restaurante('praça', 'Gourmet')
restaurante_praca._nome = 'Teste de alteração nome'
4 respostas

Olá Johnatan.

Tudo bem?

Sim, mesmo que um atributo seja definido como "privado" (com um underline antes do nome, por exemplo _nome), ele ainda pode ser alterado diretamente pela instância. Em Python, o conceito de atributos privados é mais uma convenção do que uma restrição real. O uso do underline é uma forma de indicar que o atributo não deve ser acessado diretamente, mas o Python não impede que você o faça.

Para evitar que um atributo seja alterado diretamente, você pode usar propriedades (property). Com isso, você pode definir métodos getter e setter que controlam o acesso e a modificação do atributo. Aqui está um exemplo prático de como você pode fazer isso:

class Restaurante:
    def __init__(self, nome, categoria):
        self._nome = nome.title()
        self.categoria = categoria.upper()
        self._ativo = False
        Restaurante.restaurantes.append(self)

    @property
    def nome(self):
        return self._nome

    @nome.setter
    def nome(self, novo_nome):
        self._nome = novo_nome.title()

    def __str__(self):
        return f'{self._nome} {self.categoria}'

# Exemplo de uso
restaurante_praca = Restaurante('praça', 'Gourmet')
print(restaurante_praca.nome)  # Saída: Praça

# Tentando alterar diretamente (não recomendado)
restaurante_praca._nome = 'Teste de alteração nome'
print(restaurante_praca.nome)  # Saída: Teste De Alteração Nome

# Alterando usando o setter
restaurante_praca.nome = 'novo nome'
print(restaurante_praca.nome)  # Saída: Novo Nome

Neste exemplo, o atributo _nome é tratado como privado, e o acesso a ele é feito através da propriedade nome. O método @property define um getter, e o método @nome.setter define um setter que aplica a transformação desejada (no caso, usar .title() para garantir que a primeira letra de cada palavra seja maiúscula).

Desta forma, você garante que todas as alterações ao atributo _nome passem pelo setter, permitindo que você valide ou transforme os dados conforme necessário.

Espero ter ajudado e bons estudos!

Boa Noite, Tudo bem ?

Nesse caso então , a alteração ocorreria dentro da variável novonome e não _nome?

Obrigada!

Olá Julia.

Na verdade, o valor passado no setter vai ser atribuído ao atributo nome, que continua sendo o atributo privado da classe. A propriedade nome é uma interface que você usa para acessar e modificar nome, mas a alteração real ainda ocorre dentro de nome.

Ou seja, quando você faz:

restaurantepraca.nome = 'novo nome'

Você está, na prática, chamando o método setter da propriedade nome, isso vai alterar o valor do atributo nome (não existe uma nova variável chamada novonome, apenas o atributo já existente nome).

Assim, a variável nome é que recebe o novo valor, mas isso acontece de maneira "controlada", já que passa pelo método setter, onde você pode validar ou modificar o dado antes de salvá-lo no atributo privado.

Espero ter ajudado. Qualquer dúvida, é só chamar.

Bons estudos!

Bom dia,

Ajudou sim. Obrigada