Почему управляемые атрибуты работают только для атрибутов класса, а не для атрибутов экземпляра в python? - PullRequest
2 голосов
/ 09 января 2009

Для иллюстрации вопроса проверьте следующий код:

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return self._v
  def __set__(self, obj, value):
    self._v = value
    print "set", self, obj, value
    return None

class SomeClass1(object):
  m = MyDescriptor()

class SomeClass2(object):
  def __init__(self):
    self.m = MyDescriptor()

x1 = SomeClass1()
x2 = SomeClass2()

x1.m = 1000
# ->  set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000
x2.m = 1000 # I guess that this overwrites the function. But why?
# ->
print x1.m
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000
print x2.m
# -> 10000
  1. Почему x2.m = 1000 не вызывает функцию __set __ ? Кажется, что это переписывает функцию. Но почему?
  2. Где находится _v в x1? Это не в x1._v

Ответы [ 3 ]

3 голосов
/ 09 января 2009

Вы должны прочитать это и это .

Перезаписывает функцию, потому что вы перегрузили не функции __set__ и __get__ класса SomeClass, а класса MyDescriptor. Может быть, вы хотели, чтобы SomeClass наследовал MyDescriptor? SomeClass1 печатает выходные данные «get» и «set», потому что это статический метод AFAIK. Подробнее читайте в верхних ссылках.

3 голосов
/ 09 января 2009

Чтобы ответить на ваш второй вопрос, где _v?

Ваша версия дескриптора сохраняет _v в самом дескрипторе. Каждый экземпляр дескриптора (экземпляр уровня класса SomeClass1 и все экземпляры уровня объекта в объектах класса SomeClass2 будут иметь различные значения _v.

Посмотрите на эту версию. Эта версия обновляет объект, связанный с дескриптором. Это означает, что объект (SomeClass1 или x2) будет содержать атрибут _v.

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return obj._v
  def __set__(self, obj, value):
    obj._v = value
    print "set", self, obj, value
0 голосов
/ 10 января 2009

Я нашел _v из x1 : он находится в SomeClass1 .__ dict __ ['m'] ._ v

Для версии, предложенной С.Лоттом в другом ответе: _v в x1._v

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...