Python - __getattr__()と_getattribute__()メソッドの違い

3526 ワード

python再アクセス属性のメソッドで定義されています_getattr__()と_getattribute__()2つの方法は,その違いは非常に細かいが,非常に重要である.
  • クラスが__getattribute__()メソッドを定義している場合、Pythonはプロパティまたはメソッド名を参照するたびに呼び出されます(特別なメソッド名を除き、それは嫌な無限ループを引き起こすためです).
  • クラスが__getattr__()メソッドを定義している場合、Pythonは通常の場所で属性を問合せた場合にのみ呼び出されます.インスタンスxが属性colorを定義する場合、x.colorx.__getattr__('color')を呼び出さない.x.colorが定義した値のみが返されます.

  •  
    2つの例で説明しましょう.class Dynamo(object): def __getattr__(self, key): if key == 'color': ① return 'PapayaWhip' else: raise AttributeError ② >>> dyn = Dynamo() >>> dyn.color ③ 'PapayaWhip' >>> dyn.color = 'LemonChiffon' >>> dyn.color ④ 'LemonChiffon'
  • 属性名は、__getattr()__メソッドに文字列として入力される.名前が'color'の場合、メソッドは値を返します.(この場合、ハードコーディングされた文字列にすぎませんが、いくつかの計算を正常に行い、結果を返すことができます.)
  • プロパティ名が不明な場合、__getattr()__メソッドはAttributeError例外を開始する必要があります.そうしないと、未定義のプロパティにアクセスすると、コードは黙って失敗するだけです.(技術的には、メソッドが例外を起こさないか、明示的に値を返さない場合、NoneであるPythonの空の値が返されます.これは、明示的に定義されていないすべての属性がNoneであることを意味し、ほとんど見たくないことは間違いありません.)
  • dynインスタンスにはcolorという属性がないため、計算値が与えられると__getattr__()が呼び出される.
  • はdynを明示的に設定.color以降、dynは提供する.colorの値はdynのため__getattr__()メソッドを呼び出す.colorはこのインスタンスで定義されています.

  • 一方、__getattribute__()の方法は絶対的で無条件である.class SuperDynamo(object): def __getattribute__(self, key): if key == 'color': return 'PapayaWhip' else: raise AttributeError >>> dyn = SuperDynamo() >>> dyn.color ① 'PapayaWhip' >>> dyn.color = 'LemonChiffon' >>> dyn.color ② 'PapayaWhip'
  • はdynを取得する.colorの値の場合、__getattribute__()メソッドが呼び出されます.
  • dynが明示的に設定も.dynを取得するcolorの値の場合、__getattribute__()メソッドが呼び出されます.__getattribute__()メソッドが存在する場合、インスタンスの作成後に明示的にプロパティが設定されていても、プロパティとメソッドが検索されるたびに無条件に呼び出されます.

  • クラスの__getattribute__()メソッドが定義されている場合は、__setattr__()メソッドを定義し、プロパティの値を追跡するために両者の間で協同したい場合があります.そうでなければ、インスタンスの作成後に設定した値はブラックホールに消えます.
    Pythonはクラスのメソッド名を検索するときに呼び出されるため、__getattribute__()メソッドに特に注意してください.class Rastan(object): def __getattribute__(self, key): raise AttributeError ① def swim(self): pass >>> hero = Rastan() >>> hero.swim() ② Traceback (most recent call last):
    File "", line 1, in
    File "", line 3, in __getattribute__
    AttributeError
  • クラスは、AttributeErrorの例外を常に引き起こす__getattribute__()メソッドを定義する.属性やメソッドのないクエリーは成功します.
  • hero.swim()を呼び出すと、PythonはRastanクラスでswim()メソッドを検索します.このルックアップは、すべての属性およびメソッドルックアップが__getattribute__()メソッドを通過するため、__getattribute__()メソッド全体を実行する.この例では、__getattribute__()メソッドはAttributeError例外を引き起こすため、メソッド検索プロセスは失敗し、メソッド呼び出しも失敗する.
  • "__getattr__"適切な関数または属性が見つからない場合は、デフォルトとして呼び出されます.
  • 通常、スクリプトに「_getattribute_」が含まれている場合、「_getattr_」も含まれていますの場合は「_getattr_」は呼び出されませんただし、上記の例から分かるように、"_getattribute_"エラーが表示されると、「__getattr_」も自動的に呼び出されます.