1
resposta

Ao acessar um metodo setter direto da classe, o que acontece por baixo dos panos?

Eu tenho a seguinte classe:

class MyClass:

    def method(self):
        self.__nome = None
        return 'instance method called', self

    @property
    def nome(self):
        return self.__nome, self

    @nome.setter
    def nome(self, value):
        self.__nome = value

E ao invocar direto da classe o getter nome e depois 'settar' tambem diretamente da classe ele funciona mas estas nao sao metodos estaticos.. O que ocorre por baixo dos panos? Fico confuso porque venho do mundo Java e chamar metodos assim(sem referencia), somente com metodos estaticos.

print(MyClass.nome)
<property object at 0x000001D3089EC958>
MyClass.nome = "yoyoyo"
print(MyClass.nome)
yoyoyo

Grato pela atencao!

1 resposta

Olá Thomas, tudo bem?

Quando você faz MyClass.nome = "yoyoyo", na verdade você não está inicializando a propriedade, na verdade, você está sobrescrevendo o atributo e transformando ele em string. Podemos ver isso usando a função type:

class MyClass:

    def method(self):
        self.__nome = None
        return 'instance method called', self

    @property
    def nome(self):
        return self.__nome, self

    @nome.setter
    def nome(self, value):
        self.__nome = value


print(type(MyClass.nome))
<class 'property'>

MyClass.nome = "yoyoyo"
print(type(MyClass.nome))
<class 'str'>

No Python, tudo é objeto - inclusive classes - ou seja, esses atributos conseguem ser acessados tanto pela classe quanto pelo objeto. Por exemplo, se instanciarmos um objeto depois de sobrescrever o atributo nome, esse objeto carrega o valor sobrescrito:

class MyClass:

    def method(self):
        self.__nome = None
        return 'instance method called', self

    @property
    def nome(self):
        return self.__nome, self

    @nome.setter
    def nome(self, value):
        self.__nome = value


print(type(MyClass.nome))
<class 'property'>

MyClass.nome = "yoyoyo"
print(type(MyClass.nome))
<class 'str'>

my_object = MyClass()
print(my_object.nome)
yoyoyo

my_object.nome = 'Thomas'
print(my_object.nome)
Thomas