2013-04-19 5 views
7

最近、私はofficial HOW-TO about Python descriptorsを読んでいます。実際には、これはRaymond Hettingerによって書かれたan essayです。しかし、それを数回読んだ後、私はまだそれのいくつかの部分について混乱しています。私はいくつかの段落を引用し、続いて私の混乱と質問をします。Python記述子と<Descriptor HowToガイド>についての悩み


インスタンスの辞書はデータ記述子と同じ名前のエントリがある場合は、データ記述子が優先されます。インスタンスの辞書に、非データ記述子と同じ名前のエントリがある場合は、辞書エントリが優先されます。

  • これはクラスと同じですか?辞書のデータ/非データ記述子と同じ名前のエントリがある場合、クラスの優先順位チェーンは何ですか?オブジェクトの場合

は、機械は、type(b).__dict__['x'].__get__(b, type(b))b.xを変換object.__getattribute__()です。インプリメンテーションは、データ記述子がインスタンス変数よりも優先され、インスタンス変数が非データ記述子よりも優先される優先順位チェーンによって処理され、指定されている場合は最も低い優先順位が__getattr__()に割り当てられます。

クラスの場合、機械はtype.__getattribute__()にあり、B.xB.__dict__['x'].__get__(None, B)に変換します。

  • 上記の二つの段落は、ディスクリプタの属性アクセス時に自動的に起動されるプロセスを教えてください。インスタンス(b.x)とクラス(B.x)によってアクセスされる属性の違いをリストします。しかし、ここで私の混乱は、次のとおりです。クラスの属性またはインスタンスがディスクリプタでない場合
    • 、変換は(すなわち、B.__dict__['x'].__get__(None, B)type(b).__dict__['x'].__get__(b, type(b))B.xb.xを変換)まだ進むのだろうか?このクラスまたはインスタンスの属性をdictに直接返すのは簡単ですか?
    • インスタンスの辞書に、非データ記述子と同じ名前のエントリがある場合、最初の引用符の優先順位ルールに従って、辞書エントリが優先されます。この時点で変換はまだ進行しますか?または、のdictの値を返すだけですか?

非データディスクリプタメソッドに結合機能の通常パターンのバリエーションのための簡単な機構を提供します。

  • 関数/メソッドのみを得てもよいが、をを設定することができないので、選ばれた非データディスクリプタですか?
  • 関数をメソッドにバインドするための基本的なメカニズムは何ですか?クラス辞書はメソッドを関数として格納するので、クラスとそのインスタンスをそれぞれ使用して同じメソッドを呼び出すと、最初の引数がのいずれかであるかどうかをどのように知ることができますか??属性としてアクセスしたとき、彼らは法に変換することができるように

機能__get__()方法を持っています。非データ記述子は、obj.f(*args)コールをf(obj, *args)に変換します。 klass.f(*args)を呼び出すとf(* args)になります。

  • どのように非データディスクリプタはf(obj, *args)obj.f(*args)コールを変換することができますか?
  • 非データ記述子をklass.f(*args)に変換すると、どのようにしてf(*args)にコールできますか?
  • 上記の2つの変換の根底にあるメカニズムは何ですか?クラスとインスタンスの間に違いがあるのはなぜですか?
  • 上記の状況で__get__()メソッドの役割は何を果たしますか?

答えて

2

これはクラスと同じですか?辞書のデータ/非データ記述子と同じ名前のエントリがある場合、クラスの優先順位チェーンは何ですか?

いいえ、属性がスーパークラスとサブクラスの両方で定義されている場合、スーパークラス値は完全に無視されます。

クラスの属性またはインスタンスがディスクリプタでない場合、変換は(すなわち、B.__dict__['x'].__get__(None, B))type(b).__dict__['x'].__get__(b, type(b))とBxのにBXを変換し、まだ進むのでしょうか?

をいいえ、それは直接オブジェクトを返します。あなたはすべてのオブジェクトがデフォルトで引数を無視し、selfを返すメソッド__get__()を持っていることをふり場合、はい、同等クラスの__dict__から頂いております。または。

インスタンスの辞書に、非データ記述子と同じ名前のエントリがある場合、最初の引用符の優先順位ルールに従って、辞書エントリが優先されます。この時点で変換はまだ進行しますか?あるいは、そのディクテーションの値を返すだけですか?あなたが引用された段落で明らかではないが、何

は(多分それは別の場所に書き留めています)b.xb.__dict__['x']を返すように決定したとき、何__get__はどのような場合に呼び出されていないことです。 __get__は、b.xまたはB.xという文字列がクラス dictに存在するオブジェクトを返すことを決定したときに、正確に呼び出されます。

関数/メソッドは取得できますが設定できないため、非データ記述子が選択されていますか?

はい:彼らはあなたがfこれは関数オブジェクトをオーバーライドすることができますクラスBに住む関数オブジェクトである場合でもB.f = 42を言うことができているPythonで「古いスタイル」クラスモデルの一般化、あります無関係なオブジェクトで。一方、データディスクリプタはpropertyをサポートするために異なるロジックを持っています。

メソッドをメソッドにバインドするための基本的なメカニズムは何ですか?クラス辞書はメソッドを関数として格納するので、クラスとそのインスタンスをそれぞれ使用して同じメソッドを呼び出すと、最初の引数が自己であるべきかどうかを基礎関数がどのように示しますか?

これを理解するには、「メソッドオブジェクト」が必要です。 b.f(*args)という構文は、2つのステップである(b.f)(*args)に相当します。最初のステップはf.__get__(b)です。 bとfの両方を格納するメソッドオブジェクトを返します。 2番目のステップはメソッドオブジェクトを呼び出します。メソッドオブジェクトは、bを余分な引数として追加することで元のfを呼び出します。これは、B.fの場合は発生しません。B.f、すなわちf.__get__(None, B)はf(Python 3の場合)です。特殊メソッド__get__が関数オブジェクトに対して設計されている方法です。

関連する問題