Pythonにおいて、あるオブジェクトに備わっている属性を調べる際に使用する関数としてdir
関数とhasattr
関数があるかと思いますが、
「dir
関数の実行結果には出力されないが、hasattr
関数ではTrueになる」
という事象に関して質問があります。
事象の例
たとえば__builtins__
に__dict__
属性がある調査したいとき、hasattr
関数を使用すると「True」が返ってきます。
※Pythonのバージョンは3.9です。
Python
1#Trueと出力される 2print(f'{hasattr(__builtins__,"__dict__")=}')
しかし、__builtins__
に対してdir
関数を実行した場合、出力結果に__dict__
は存在しません。
Python
1#出力結果に__dict__は存在しない 2print(f'{dir(__builtins__)=}')
実際に__builtins__
から__dict__
属性を参照することはできるため、hasattr
関数の結果の方が正しいかと思います。
Python
1#問題なく参照できる 2print(f'{__builtins__.__dict__=}')
お聞きしたいこと
この事象について2点お聞きしたいことがあります。
【質問1】dir
関数は、実行結果として「そのオブジェクトに備わっているすべての属性を出力するとは限らない」という認識でよいのでしょうか。
__builtins__
は、以下のコードの結果から__dir__()
というメソッドを持つかと思います。
Python
1#Trueが返ってくる 2print(f'{hasattr(__builtins__,"__dir__")=}') 3 4#エラーにならず呼び出し可能 5print(__builtins__.__dir__())
公式ドキュメントにて、dir
関数の項目には
オブジェクトが
__dir__()
という名のメソッドを持つなら、そのメソッドが呼び出され、属性のリストを返さなければなりません。これにより、カスタムの__getattr__()
や__getattribute__()
関数を実装するオブジェクトは、dir() が属性を報告するやり方をカスタマイズできます。
とあり、また、
dir()
は主に対話プロンプトでの使用に便利なように提供されているので、厳密性や一貫性を重視して定義された名前のセットというよりも、むしろ興味を引くような名前のセットを返そうとします。また、この関数の細かい動作はリリース間で変わる可能性があります。例えば、引数がクラスであるとき、メタクラス属性は結果のリストに含まれません。
とあります。
これらの記述から、今回例に挙げた__builtins__
が__dict__
属性を備えているか否かについては
①__builtins__
オブジェクトは__dict__
属性を備えている
②dir
関数は引数に与えられたオブジェクトのが備えるすべての属性を出力するとは限らずない
③__builtins__
をdir関数の引数に与えて実行したとき、__dict__
属性は②の例に該当し、出力されなかった。
という認識でよいのでしょうか。
【質問2】とあるオブジェクトが備える属性を確認したいときにベストな手法について
今回の__builtins__
に対するhasattr
関数とdir
関数の挙動からすると、とあるオブジェクトが備える属性を確認したいときにはhasattr
関数の方がより確実な結果を得ることができるように見えるのですが、実際のところはどうなのでしょうか。
また、もしもhasattr
関数の方がdir
関数よりより確実な結果を得ることができたとしても、さらにhasattr
関数より良い関数や手法があるのでしょうか。
詳しい方、教えていただけますと幸いです。
よろしくお願いいたします。

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。