まったく同じではありません。およびが検出する属性を省略するdir()
診断ツールです。getattr()
hasattr()
dir()
ドキュメントから:
デフォルトのメカニズムは、完全な情報ではなく最も関連性dir()
の高い情報を生成しようとするため、オブジェクトの種類によって動作が異なります。
- オブジェクトがモジュール オブジェクトの場合、リストにはモジュールの属性の名前が含まれます。
- オブジェクトが型またはクラス オブジェクトの場合、リストにはその属性の名前と、そのベースの属性が再帰的に含まれます。
- それ以外の場合、リストには、オブジェクトの属性の名前、そのクラスの属性の名前、およびそのクラスの基本クラスの属性の再帰的な名前が含まれます。
と
注:は、主にインタラクティブ プロンプトでの使用を便利にするdir()
ために提供されているため、厳密にまたは一貫して定義された名前のセットを提供しようとするよりも、興味深い名前のセットを提供しようとします。詳細な動作は、リリース間で変わる可能性があります。たとえば、引数がクラスの場合、属性は結果リストに含まれません。metaclass
鉱山を強調します。
これは、メタクラスが提供する属性hasattr()
を見つけることを意味しますが、そうではなく、関数の定義はデバッグの利便性を提供するためのものであり、完全性を提供するためのものではないため、見つかったものは Python リリース間で異なる可能性があります。dir()
特定のメタクラス シナリオのデモ。hasattr()
メタクラスで定義された属性が見つかります。
>>> class Meta(type):
... foo = 'bar'
...
>>> class Foo(metaclass=Meta):
... pass
...
>>> hasattr(Foo, 'foo')
True
>>> 'foo' in dir(Foo)
False
最後だが大事なことは:
オブジェクトに という名前のメソッドがある場合__dir__()
、このメソッドが呼び出され、属性のリストを返す必要があります。
これは、メソッドが実装されている場合、「見つかった」属性がさらに大きく異なる可能性があることhasattr()
を意味します。dir()
.__dir__()
に固執するだけhasattr()
です。1 つには、属性のテストは 1 つ以上の辞書に対するメンバーシップ テストであるため安価であるため、より高速です。一方、すべてのディクショナリ キーを列挙し、それらをインスタンス、クラス、および基本クラス全体でマージすると、CPU コストがはるかに高くなります。