質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

559閲覧

Pythonでのdir関数とhasattr関数の実行結果の違いについて教えてください。

exnjinia

総合スコア16

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/06/25 07:35

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関数より良い関数や手法があるのでしょうか。

詳しい方、教えていただけますと幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

※ 本題とは関係ありませんが、参考までに回答します。

__builtins__ とは何かと言いますと、モジュールであります。(モジュールクラスのインスタンス)

python

1>>> type(__builtins__) 2<class 'module'>

dir 関数の説明を確認してみると、for a module object: the module's attributes. と記載されています。

python

1>>> help(dir) 2Help on built-in function dir in module builtins: 3 4dir(...) 5 dir([object]) -> list of strings 6 7 If called without an argument, return the names in the current scope. 8 Else, return an alphabetized list of names comprising (some of) the attributes 9 of the given object, and of attributes reachable from it. 10 If the object supplies a method named __dir__, it will be used; otherwise 11 the default dir() logic is used and returns: 12 13 for a module object: the module's attributes. 14 for a class object: its attributes, and recursively the attributes of its bases. 15 16 for any other object: its attributes, its class's attributes, and 17 recursively the attributes of its class's base classes.

ここで、for a class object: its attributes, and recursively the attributes of its bases. と書かれていますので、module クラスに対して dir() を実行してみます。

python

1>>> dir(type(__builtins__)) 2['__annotations__', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

__dict__ の存在を確認することができます。

投稿2023/06/25 08:16

melian

総合スコア21106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

「そのオブジェクトに備わっているすべての属性を出力することはできない」のは

python

1class T: 2 def __getattr__(self, s): 3 return s

この様なクラスを定義したら明らかです。

投稿2023/06/26 03:29

quickquip

総合スコア11299

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

この回答はGPT-4による自動生成回答です

【質問1】の回答:

はい、その認識で正しいです。dir()関数は、オブジェクトが持つすべての属性を出力するとは限りません。dir()関数は主に対話プロンプトでの使用に便利なように提供されており、厳密性や一貫性を重視して定義された名前のセットというよりも、むしろ興味を引くような名前のセットを返そうとします。また、この関数の細かい動作はリリース間で変わる可能性があります。

【質問2】の回答:

hasattr()関数は、特定の属性がオブジェクトに存在するかどうかを確認するための関数です。一方、dir()関数は、オブジェクトが持つ属性のリストを返す関数です。どちらの関数がベストかは、目的によって異なります。

  • 特定の属性がオブジェクトに存在するかどうかを確認したい場合: hasattr()関数を使用するのがベストです。
  • オブジェクトが持つ属性のリストを取得したい場合: dir()関数を使用するのがベストですが、すべての属性がリストされるとは限らないことに注意してください。

さらに良い関数や手法については、Pythonの標準ライブラリにはinspectモジュールがあります。このモジュールは、オブジェクトの情報を取得するための高度な関数を提供しています。例えば、inspect.getmembers()関数は、オブジェクトのすべてのメンバー(属性とメソッド)をタプルのリストとして返します。これにより、より詳細な情報を取得することができます。

python

1import inspect 2 3# オブジェクトのすべてのメンバーを取得 4members = inspect.getmembers(__builtins__) 5 6# メンバー名と値のタプルのリストを表示 7print(members)

ただし、inspectモジュールは主にデバッグやインタラクティブな探索のために使用されることが多く、通常のプログラムでの使用はあまり一般的ではありません。そのため、hasattr()dir()関数が目的に応じて適切な選択肢であることが多いです。

投稿2023/06/25 07:37

teratail-ai

Powered by GPT-4

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問