Поведение атрибута в классе python с использованием декоратора свойств - PullRequest
1 голос
/ 17 июня 2020

Меня смущает поведение переменных атрибутов в моем классе при использовании декоратора свойств.

См. Этот пример:

class Example:
  def __init__(self, x):
    self.x = x

  @property
  def x(self):
    return self.__x

  @x.setter
  def x(self, x):
    self.__x = x

Это работает нормально, но как? Переменная внутри свойства установщика (self.__x) не была «определена» в конструкторе, поэтому как ей можно присвоить значение?

Другие вещи также работают, например, возьмите тот же класс, что определен выше и добавьте к нему новую функцию-член:

  def set_val_x(self):
    self.__x = 8765

Опять же, использование этой функции действительно работает, аналогично property.setter (но не использует декоратор свойств).

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Внутри __init__ строка

self.x = x

больше не является сокращением для

setattr(self, 'x', x)

, поскольку существует атрибут класса Example.x. Вы больше не создаете атрибут экземпляра x, а вызываете

type(self).X.__set__(self, 'x', x)

, который устанавливает атрибут экземпляра __x.

Атрибуты экземпляра могут быть созданы, изменены или удалены в в любой момент. Метод __init__ - это просто удобное единое место для их создания, потому что он вызывается автоматически каждый раз, когда вы создаете экземпляр.

0 голосов
/ 17 июня 2020

В Python вам не нужно определять переменные в конструкторе. Вы можете назначить их, когда захотите. Например,

class Foo:
    def __init__(self, bar):
        self.bar = bar
my_foo = Foo(3)
my_foo.other_thing = 6

совершенно законно.

...