私はpythonが初めてです。クラスオブジェクトにはbases属性があるのに対し、非クラスオブジェクトにはbases属性がないと思います。しかし、よくわかりません。python\cpython は、オブジェクトが非クラスかクラスかをどのようにチェックし、それに応じて属性アクセス中に正しい引数をオブジェクトの記述子属性に渡しますか?
============================================
更新しました:
__getattribute__
私は、 と記述子がどのように連携して制限付きメソッドを作成するかを学んでいました。クラスオブジェクトと非クラスオブジェクトがどのように記述子を__get__
異なる方法で呼び出すのか疑問に思っていました。これら 2 種類のオブジェクトは同じ__getattribute__
CPython 関数を共有しており、その同じ関数は、呼び出し元のオブジェクトがクラスか非クラスかを認識している必要があると考えました。しかし、私は間違っていました。この記事はそれをよく説明しています:
http://docs.python.org/dev/howto/descriptor.html#functions-and-methods
したがって、クラスオブジェクトは使用しますtype.__getattribute__
が、非クラスオブジェクトは使用しますobject.__getattribute__
。それらは異なる CPython 関数です。また、superには 3 つ目の__getattribute__
CPython 実装もあります。
ただし、スーパー1 については、上記の記事には次のように記載されています。
super() によって返されるオブジェクトには、記述子を呼び出すためのカスタム _ getattribute _() メソッドもあります。呼び出し super(B, obj).m() は、obj._ class _._ mro _ で B の直後の基本クラス A を検索し、A._ dict _['m']._ get _(obj, A)。記述子でない場合、m は変更されずに返されます。辞書にない場合、m はobject._getattribute_ ()を使用した検索に戻ります。
上記のステートメントは、Python3.1 での私の実験と一致していないようです。私が見たのは、私にとって合理的です:
super(B, obj).m ---> A.__dict__['m'].__get__(obj, type(obj))
objclass = タイプ(obj)
super(B, objclass).m ---> A.__dict__['m'].__get__(None, objclass)
Aは渡されませんでした__get__
objclass (ではなくA ) の mro チェーンは、特に 2 番目のケースでm内に必要なものであると私は信じているので、私にとっては合理的です。
私は何か間違ったことをしていましたか?それとも、正しく理解できていませんでしたか?