2016-04-24 6 views
2

__weakref__は弱い参照に関連しています。私は弱い参照の背後に全体のアイデアを取得し、私はそれらを使用する可能性があります。私は取得しない唯一のことは、以下で説明します。なぜクラス.__ weakref__なし、インスタンス.__ weakref__はNoneですか?

例えば、属性__weakref__自身を持っているクラスは異なる、したがって、インスタンスクラスから継承__weakref__、これはそのA.__weakref__を意味しません。 A().__weakref__と同じでなければなりません:インスタンスはクラスから__weakref__を継承するが、instance.__weakref__Noneている間

>>> 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のですか?

+0

*「これは '.__ weakref__ことを意味'は' A().__ weakref__' "*と同じです - 明らかにそうではないので、*"インスタンスはクラス "*から' __weakref__'を継承します。 'A .__ weakref__はA().__ weakref__'は' False'と評価されます。 – jonrsharpe

答えて

3

クラスは、__weakref__descriptor objectです。これはちょうどpropertyまたはメソッドのように機能します。オブジェクトの属性にアクセスするときにのみ自動的にバインドされます。弱参照の実際のデータは、Pythonがメモリ内のクラスとインスタンスを表すために使用するデータ構造の一部であるC構造体に格納されます。

このように、インスタンスには独自の__weakref__属性は必要ありません。クラス記述子はインスタンスデータ構造体にバインドされており、Cコードは必要な情報を取得するために正しいC構造体を探します。

クラスの属性にアクセスすると、ディスクリプタオブジェクト自体が生成されます。これはNoneではありません。それは記述子オブジェクトです。属性では、バインドされた属性によって弱い参照が生成されます。弱い参照がない場合は、Noneが返されます。

あなたは、直接その上__get__を呼び出して、(通常のtype.__getattribute__()結合挙動をバイパスする)A.__dict__['__weakref__']経由でオブジェクトにアクセスすることにより、再作成する記述子の動作することができます:

>>> 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> 
関連する問題