各オブジェクトには、その変数と関数を含む属性のディクショナリがあります。これらの辞書を参照してください。
If an instance’s dictionary has an entry with the same name as a data descriptor,
the data descriptor takes precedence. If an instance’s dictionary has an entry with
the same name as a non-data descriptor, the dictionary entry takes precedence.
これは彼らが話していたことです。
これを表示するには:
#data descriptor
class A(object):
def __get__(self, obj, type):
print "hello from get A"
def __set__(self, obj, val):
print "hello from set A"
#non data descriptor
class B(object):
def __get__(self, obj, type):
print "hello from get B"
class C(object):
#our data descriptor
a = A()
#our non data descriptor
b = B()
>>> c = C()
>>> c.a
hello from get A
>>> c.b
hello from get B
>>> c.a = 0
hello from set A
>>> c.a #notice after reassignment, A.__get__ is still called
hello from set A
>>> c.b = 0 #instance variable with the same name as the non data-descriptor
>>> c.b #notice how B.__get__ isn't called anymore
0
基本的には、__get__
と__set__
がオブジェクト (データ記述子) に対してユーザー定義されている場合、デフォルトのメソッドの代わりに呼び出されるということです。__get__
オブジェクト(非データ記述子)に対してユーザーが定義した場合のみ、インスタンスはインスタンス変数を再割り当てできます。
g.x = 0
x がデータ記述子の場合、x のユーザー定義メソッドが呼び出さ__set__
れ、x がインスタンス変数または非データ記述子の場合、デフォルトの動作が呼び出されます。
データ記述子を使用すると、クラスは変数へのすべてのアクセスと変更を制御します。データ記述子型の変数へのすべてのアクセスは、 および を経由__get__
し__set__
ます。そのため、クラスが定義した方法で call と ca が変更されますc.a = 0
。A.__set__
タイプ A ではないインスタンス変数 'ca' を作成する方法はありません。
データ記述子以外の場合、クラスはアクセスのみを制御するため、c.b = 0
が呼び出されると、__set__
が定義されていないため、新しいインスタンス変数が作成されます (デフォルトの動作)。変数の設定に関するユーザー定義の動作はないため、動作なしで同じ名前のインスタンス変数を作成できます__get__
。
彼らが話している優先順位は、2 つのダイナミクスです。データ記述子は常に__get__
andを呼び出す__set__
ため、インスタンス変数を同じ名前で作成することはできません。__get__
非データ記述子は、同じ名前のインスタンス変数が作成されるまでのみ呼び出されます。