Establecedor de la propiedad no funciona cuando el atributo se inicia con "__"?

0

Pregunta

Estoy usando Python 3.8.6 y este funciona bien

class A:
    @property
    def _a(self):
        return getattr(self, '_a_', 0)

    @_a.setter
    def _a(self, value):
        self._a_ = value


a = A()
print(a._a)  # prints 0
a._a = 10
print(a._a)  # prints 10 as expected

Esto no funciona

class A:
    @property
    def _a(self):
        return getattr(self, '__a', 0)

    @_a.setter
    def _a(self, value):
        self.__a = value

a = A()
print(a._a)  # prints 0
a._a = 10
print(a._a)  # prints 0 again

Que alucinante! la única diferencia entre el primero y el segundo ejemplo es que el atributo privado __a en lugar de _a_

Alguna idea de por qué? Yo no era capaz de averiguar

properties python
2021-11-20 09:49:15
1

Mejor respuesta

1

Es por privado el nombre de destrozarlo, pero no se aplican a los contenidos de los literales de cadena como la que usted está pasando a getattr().

Afortunadamente la solución es simple:

class A:
    @property
    def _a(self):
        return getattr(self, '_A__a', 0)

    @_a.setter
    def _a(self, value):
        self.__a = value

a = A()
print(a._a)  # prints 0
a._a = 10
print(a._a)  # prints 10 now
2021-11-20 15:39:03

Creo que la variante de usar classname pausa para el subclases, ya que la carta está escrita en la clase base para el atributo nombre todavía serán alterados para _A__a.
kaya3

@kaya3: "romper" qué sentido? Se usa el nombre de la subclase en uno.
martineau

Bueno, si class B(A): pass entonces b = B(); b._a = 23; print(b._a) imprimir 0 debido a que el compositor escribe _A__a pero el captador intenta acceder a _B__a.
kaya3

@kaya3: estás en lo correcto, así que me quita esa parte de mi respuesta.
martineau

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................