2014-02-05 2 views
0

Я смотрел на документации дескриптора питона в here, и заявление, которое заставило меня думать, это:Python дескриптор - Документация неясная


Для объектов, машины в object.__getattribute__(), который трансформирует b.x в type(b).__dict__['x'].__get__(b, type(b))


под рубрикой Invoking Descriptors.

Последняя часть заявления b.x into type(b).__dict__['x'].__get__(b, type(b)) вызывает конфликт здесь. По моему пониманию, если мы ищем атрибут на экземпляре, то instance.__dict__ просматривается, и если мы не найдем ничего, ссылается на type(instance).__dict__.

В нашем примере, b.x затем следует оценивать как:

b.__dict__["x"].__get__(b, type(b))вместо

type(b).__dict__['x'].__get__(b, type(b))

Является ли это понимание правильно? Или я ошибаюсь в интерпретации? Любое объяснение было бы полезно.

Спасибо.

Я добавляю вторую часть, а также:

Почему атрибуты экземпляра не уважает протокол дескриптора? Например: приведенный ниже код:

>>> class Desc(object): 
...  def __get__(self, obj, type): 
...   return 1000 
...  def __set__(self, obj, value): 
...   raise AttributeError 
... 
>>> 
>>> class Test(object): 
...  def __init__(self,num): 
...   self.num = num 
...   self.desc = Desc() 
... 
>>> 
>>> t = Test(10) 
>>> print "Desc details are ", t.desc 
Desc details are <__main__.Desc object at 0x7f746d647890> 

Спасибо, что помогли мне.

ответ

1

Ваше понимание неверное. x, скорее всего, вообще не отображается в dict экземпляра; объект дескриптора появляется в указателе класса или в типе одного из суперклассов.

Давайте использовать пример:

class Foo(object): 
    @property 
    def x(self): 
     return 0 

    def y(self): 
     return 1 

x = Foo() 
x.__dict__['x'] = 2 
x.__dict__['y'] = 3 

Foo.x и Foo.y являются дескрипторы. (Свойства и функции и реализуют протокол дескриптора.)

Когда мы достигаем x.x:

>>> x.x 
0 

Мы не получаем значение из Словаре x «s. Вместо этого, так как Python находит дескриптор данных по имени x в Foo.__dict__, он вызывает

Foo.__dict__['x'].__get__(x, Foo) 

и возвращает результат. Дескриптор данных выигрывает над экземпляром dict.

С другой стороны, если мы попытаемся x.y:

>>> x.y 
3 

мы получаем 3, а не связанный объект метода. Функции не имеют __set__ или __delete__, поэтому экземпляр dict переопределяет их.


Что касается новой части 2 вашего вопроса, дескрипторы не работают в экземпляре dict. Подумайте, что произойдет, если они:

class Foo(object): 
    @property 
    def bar(self): 
     return 4 

Foo.bar = 3 

Если дескрипторы функционировали экземпляр Словаря, то назначение Foo.bar бы найти дескриптор в Словаре Foo «s и вызвать Foo.__dict__['bar'].__set__. Метод дескриптора __set__ должен обрабатывать установку атрибута как для класса, так и для экземпляра, и он должен каким-то образом объяснить разницу даже перед лицом метаклассов. Там просто нет веской причины усложнять протокол таким образом.

+0

Спасибо за отличное объяснение. –

+0

Что делать, если у нас есть что-то вроде: >>> класс Desc (объект): ... Защита __get __ (я, OBJ, типа): ... вернуть 1000 ... Защита __set __ (я, OBJ, значение): ... поднять AttributeError ... >>> >>> класс Test (объект): ... защиту __init __ (я, NUM): ... self.num = Num . .. self.desc = Desc() ... >>> >>> t = Test (10) >>> print «Подробности о заказе», t.desc Детали описания <__ main __. Desc object при 0x7f746d647890> Почему атрибуты экземпляра не учитывают протокол дескриптора? –

+0

Я добавил вторую часть, пожалуйста, обновите ответ и объясните это. –

Смежные вопросы