7

以下の例では、attributeが存在するにxもかかわらず、オブジェクトのスロットからアクセスされます(これは典型的またはおそらく有用なケースではありませんが、私は興味があります):x__dict__

>>> class C(object):
...     __slots__ = 'x'
...     
>>> class D(C):
...     pass
... 
>>> obj = D()
>>> obj.x = 'Stored in slots'
>>> obj.__dict__
{}
>>> obj.__dict__['x'] = 'stored in __dict__'
>>> obj.x
'Stored in slots'

このアクセス順序 (スロットが最初) は文書化された動作ですか? または単に実装の詳細ですか?

4

1 に答える 1

11

はい、__dict__オブジェクトのは、データ記述子が参照された後にのみ参照されます。__slots__属性はデータ記述子として実装されます。

記述子の呼び出しを参照してください。

インスタンスバインディングの場合、記述子呼び出しの優先順位は、定義されている記述子メソッドによって異なります。記述子は、、およびの任意の組み合わせを定義__get__()でき__set__()ます__delete__()。が定義されていない場合__get__()、オブジェクトのインスタンスディクショナリに値がない限り、属性にアクセスすると記述子オブジェクト自体が返されます。記述子が定義__set__()および/またはの場合__delete__()、それはデータ記述子です。どちらも定義していない場合は、非データ記述子です。通常、データ記述子はとの両方__get__()を定義します__set__()が、非データ記述子には__get__()メソッドのみがあります。定義されたデータ記述子は__set__()__get__()常にインスタンスディクショナリの再定義を上書きします。対照的に、非データ記述子はインスタンスによってオーバーライドできます。

そして同じページから、スロットのセクション

__slots__変数名ごとに記述子(Implementing Descriptors)を作成することにより、クラスレベルで実装されます。その結果、クラス属性を使用して、__slots__;で定義されたインスタンス変数のデフォルト値を設定することはできません。そうしないと、class属性が記述子の割り当てを上書きします。

于 2013-02-28T15:22:03.080 に答える