2016-04-24 4 views
2

__weakref__ относится к слабым ссылкам. Я понимаю всю идею слабых ссылок и где я могу их использовать. Единственное, что я не получаю описывается в следующем:Почему класс .__ weakref__ not None, а экземпляр .__ weakref__ is None?

Экземпляр не имеет атрибут __weakref__ сам, отличный от класса, поэтому экземпляр наследует__weakref__ из класса, это означает, что A.__weakref__ должны быть такими же, как A().__weakref__:

>>> class A: pass 
... 
>>> A().__dict__   # Each instance starts out as an empty namespace 
{} 
>>> A.__weakref__ is None; 
False 
>>> A().__weakref__ is None #But this is True! 
True 

Почему A.__weakref__ не None пока instance.__weakref__ является None хотя экземпляры наследуют __weakref__ из класса?

+0

* "это означает, что' A .__ weakref__ 'такой же, как' A() .__ weakref__' "* - явно нет, поэтому ваше предположение о том, что *" экземпляры наследуют '__weakref__' из класса" *, неверно. 'A .__ weakref__ is A() .__ weakref__' оценивает значение' False'. – jonrsharpe

ответ

3

A класс имеет __weakref__descriptor object; это действует как property или метод; только когда вы получаете доступ к атрибуту объекта, он автоматически привязывается. Фактические данные для слабой ссылки хранятся в структуре C, которая является частью структуры данных, используемой Python для представления классов и экземпляров в памяти.

Таким образом, экземплярам не нужен свой собственный атрибут __weakref__. Дескриптор класса привязан к структуре данных экземпляра, а код C затем просто смотрит в нужную C-структуру для получения необходимой информации.

Доступ к атрибуту класса, создает сам объект дескриптора. Это не None; это объект дескриптора. По атрибуту атрибут bound создает слабые ссылки. Нет слабых ссылок, возвращается None.

Вы можете воссоздать поведение дескриптора путем доступа к объекту через A.__dict__['__weakref__'] (в обход нормального type.__getattribute__() связывания поведения), затем непосредственно вызывая __get__ по этому поводу:

>>> import weakref 
>>> class A(object): pass 
... 
>>> a = A() 
>>> A.__weakref__ 
<attribute '__weakref__' of 'A' objects> 
>>> descriptor = A.__dict__['__weakref__'] 
>>> descriptor.__get__(None, A) 
<attribute '__weakref__' of 'A' objects> 
>>> a = A() 
>>> a.__weakref__ is None 
True 
>>> descriptor.__get__(a) is None 
True 
>>> wr = weakref.ref(a) # add a weak reference 
>>> wr 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 
>>> a.__weakref__ 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 
>>> descriptor.__get__(a) 
<weakref at 0x10bd86d68; to 'A' at 0x10bad3588> 

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

  • Нет связанных вопросов^_^