【Python】属性の一覧を取得する方法(2種類)

Python

Python の各種オブジェクトが持っている属性(メンバー)の一覧を取得する方法です。

属性ぞくせいといえば attributeアトリビュート

変数名からドット . でアクセスできるメンバー変数やメンバー関数(メソッド)のことです。

それらの一覧を取得する方法です。

使用できる属性を探すときは、『組み込み関数の dir()〔ディーアイアール、ダー〕』と『 inspectインスペクト モジュールの inspect.getmembers()〔ゲットメンバース〕』が便利でした。

inspect.getmembers() は、import inspect を実行すると使用できます。

2つの使い分けです。

自分は、dir() で見つからなければ inspect.getmembers() を使う、という感じで使用しています。

ほかにも、自作クラスの設定確認をしたい時などには、組み込み関数の vars()〔バース〕 が便利でした。dir() 関数と同じ手軽さで使用することができて、『属性の名前』と『属性の値』を辞書として確認することができました。

dir() で属性を確認

属性名ぞくせいめい』の一覧を見るときは、Visual Studio Code のウォッチ式(ウォッチウィンドウ)に、dir(変数名) と書きます。

これで見ることができました。

デバッグモードで一時停止してから dir(変数名) を入力しました。

inspect.getmembers() で属性を確認

dir(変数名) の代わりに inspect.getmembers(変数名) を使用したら、『属性名』と『現在の値』の一覧が見れました。

さらに、属性の中から関数的かんすうてきなものを探すときは

[x for x in inspect.getmembers(変数名) if callable(x[1])]

で確認できました。callableコーラブル() は Python の組み込み関数です。

逆に、属性の中からあたいのようなものを探すときは

[x for x in inspect.getmembers(変数名) if not callable(x[1])]

で確認できました。

x[1] には『現在の属性の値(オブジェクト)』が入っていました。

それを、callable() に渡して判定しています。

Python マニュアル

Python マニュアルの場所です。

ディーアイアール関数(ダー関数)
(Python) dir([object])

インスペクト ゲットメンバース メソッド
(Python) inspect.getmembers(object[, predicate])

特殊属性の説明など
(Python) inspect 型とメンバー

コーラブル関数(呼び出し可能オブジェクトの判定)
(Python) callable(object)

属性ぞくせい(Attribute)の説明。

(Python) 属性(用語集)

(Python) attribute (Glossary)

methodメソッド の説明。

(Python) 関数を定義する(Python チュートリアル)

(Python) メソッドとは何ですか?(Python よくある質問 ⇒ プログラミング FAQ)

使い分け

自分は、dir() で見つからなければ inspect.getmembers() を使う、という感じで使用しています。

たいていのケースでは dir() で十分でした。

ですが、一部表示されない属性もありましたので、その時は inspect.getmembers() を使用しています。

inspect.getmembers() は、『属性の種類』を選んで取得できるところが便利でした。

『属性名』と『現在の値(オブジェクト)』のタプルが取得できたので、自在に分けて表示することができました。

属性の中から、関数だけを取得したり、メソッドだけを取得したり、値だけを取得したり、といったことができました。

inspect.getmembers() が列挙した属性の数は、dir() と同じか、それよりも多かったです。

__class____name__ などの特殊属性とくしゅぞくせいも、すべてチェックすることができました。

モジュールをインポート import inspect しておく必要がありましたが、dir() で見つからなかったときは、inspect.getmembers() が便利でした。

dir() の使用例

BeautifulSoup に dir() を使用したコード例です。

"""attribute_dir.py"""
from bs4 import BeautifulSoup

# HTML ソースを決める
source = """<!DOCTYPE html><html lang="ja">
<head><meta charset="UTF-8"><title>タイトル</title></head>
<body><h1>見出し</h1><p>本文。</p></body>
</html>"""

# BeautifulSoup のオブジェクトを取得
soup = BeautifulSoup(source, features="html.parser")

# 属性 (attribute、メンバー) を取得
attributes = dir(soup)

# 属性を表示
n_max = len(attributes)
for (n, attribute) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute}')

    # (表示例)
    # 1/180 ASCII_SPACES
    # 2/180 DEFAULT_BUILDER_FEATURES   
    # 3/180 NO_PARSER_SPECIFIED_WARNING
    # 4/180 ROOT_TAG_NAME
    # 5/180 __bool__
    # 6/180 __call__
    # 7/180 __class__
    # 8/180 __contains__
    # ...
    # 179/180 unwrap
    # 180/180 wrap

inspect.getmembers() の使用例

BeautifulSoup に inspect.getmembers() を使用したコードです。

『すべての属性を取得する場合』と『属性の種類を指定して取得する場合』のコード例を書きました。

すべての属性を取得

inspect.getmembers() に、調べたいオブジェクトを渡しています。

"""attribute_getmembers_all.py"""
import inspect
from bs4 import BeautifulSoup

# HTML ソースを決める
source = """<!DOCTYPE html><html lang="ja">
<head><meta charset="UTF-8"><title>タイトル</title></head>
<body><h1>見出し</h1><p>本文。</p></body>
</html>"""

# BeautifulSoup のオブジェクトを取得
soup = BeautifulSoup(source, features="html.parser")

# すべての属性 (attribute、メンバー) を取得
attributes = inspect.getmembers(soup)

# 属性を表示
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (表示例)
    # 1/180 ASCII_SPACES <class 'str'>
    # 2/180 DEFAULT_BUILDER_FEATURES <class 'list'>  
    # 3/180 NO_PARSER_SPECIFIED_WARNING <class 'str'>
    # 4/180 ROOT_TAG_NAME <class 'str'>
    # 5/180 __bool__ <class 'method'>
    # 6/180 __call__ <class 'method'>
    # 7/180 __class__ <class 'type'>
    # 8/180 __contains__ <class 'method'>
    # ...
    # 179/180 unwrap <class 'method'>
    # 180/180 wrap <class 'method'>

属性の種類を指定して取得

inspect.getmembers() で、調べたいオブジェクトに加えて、取得する『オブジェクトの種類』を渡しています。

また、組み込み関数の callable() を使用して、『関数的なもの』と『値のようなもの』をそれぞれ分けて取得しています。

これで、属性がたくさんあったケースでも、だいぶ探しやすくなりました。

"""attribute_getmembers_type.py"""
import inspect
from bs4 import BeautifulSoup

# HTML ソースを決める
source = """<!DOCTYPE html><html lang="ja">
<head><meta charset="UTF-8"><title>タイトル</title></head>
<body><h1>見出し</h1><p>本文。</p></body>
</html>"""

# BeautifulSoup のオブジェクトを取得
soup = BeautifulSoup(source, features="html.parser")


print('(1/5) 属性から『メソッド (method)』を取得 & 表示')
attributes = inspect.getmembers(soup, inspect.ismethod)
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (メソッドの表示例)
    # 1/106 __bool__ <class 'method'>
    # 2/106 __call__ <class 'method'>
    # 3/106 __contains__ <class 'method'>
    # 4/106 __copy__ <class 'method'>
    # 5/106 __delitem__ <class 'method'>
    # 6/106 __eq__ <class 'method'>
    # 7/106 __getattr__ <class 'method'>
    # ...
    # 105/106 unwrap <class 'method'>
    # 106/106 wrap <class 'method'>


print('\n(2/5) 属性から『関数 (function)』を取得 & 表示')
attributes = inspect.getmembers(soup, inspect.isfunction)
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (関数の表示例)
    # 1/1 _check_markup_is_url <class 'function'>


print('\n(3/5) 属性から『ジェネレーター (generator)』を取得 & 表示')
attributes = inspect.getmembers(soup, inspect.isgenerator)
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (ジェネレーターの表示例)
    # 1/8 descendants <class 'generator'>
    # 2/8 next_elements <class 'generator'>
    # 3/8 next_siblings <class 'generator'>
    # 4/8 parents <class 'generator'>
    # 5/8 previous_elements <class 'generator'>
    # 6/8 previous_siblings <class 'generator'>
    # 7/8 strings <class 'generator'>
    # 8/8 stripped_strings <class 'generator'>


print('\n(4/5) 属性を取得 &『カッコ()を付けて呼び出せるもの』を表示')
attributes = inspect.getmembers(soup)
attributes = [x for x in attributes if callable(x[1])]
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (callable な属性の表示例)
    # 1/126 __bool__ <class 'method'>
    # 2/126 __call__ <class 'method'>
    # 3/126 __class__ <class 'type'>
    # 4/126 __contains__ <class 'method'>
    # 5/126 __copy__ <class 'method'>
    # 6/126 __delattr__ <class 'method-wrapper'>
    # ...
    # 24/126 __ne__ <class 'method'>
    # 25/126 __new__ <class 'builtin_function_or_method'>
    # 26/126 __reduce__ <class 'builtin_function_or_method'>
    # ...
    # 48/126 currentTag <class 'bs4.BeautifulSoup'>
    # 49/126 decode <class 'method'>
    # ...
    # 125/126 unwrap <class 'method'>
    # 126/126 wrap <class 'method'>


print('\n(5/5) 属性を取得 &『カッコ()を付けて呼び出せないもの』を表示')
attributes = inspect.getmembers(soup)
attributes = [x for x in attributes if not callable(x[1])]
n_max = len(attributes)
for (n, (attribute, value)) in enumerate(attributes, start=1):
    print(f'{n}/{n_max} {attribute} {type(value)}')

    # (not callable な属性の表示例)
    # 1/54 ASCII_SPACES <class 'str'>
    # 2/54 DEFAULT_BUILDER_FEATURES <class 'list'>
    # 3/54 NO_PARSER_SPECIFIED_WARNING <class 'str'>
    # 4/54 ROOT_TAG_NAME <class 'str'>
    # 5/54 __dict__ <class 'dict'>
    # 6/54 __doc__ <class 'str'>
    # 7/54 __module__ <class 'str'>
    # 8/54 __weakref__ <class 'NoneType'>
    # 9/54 _is_xml <class 'bool'>
    # ...
    # 50/54 string <class 'NoneType'>
    # 51/54 strings <class 'generator'>
    # 52/54 stripped_strings <class 'generator'>
    # 53/54 tagStack <class 'list'>
    # 54/54 text <class 'str'>

vars() で __dict__ 属性を確認

ほかにも、コード例は省略しますが、組み込み関数の vars() がとても便利でした。使い方は、vars(変数名) と書くだけでした。

(Python) vars([object]) バース関数

変数に入れたオブジェクトが __dict__ 属性を持つ場合に限られましたが、変数名からドット . でアクセスできる『属性名』と『属性の値』が、『辞書 <class 'dict'>』や『辞書のように参照できる型 <class 'mappingproxy'>』として取得できました。

(Python) object.__dict__ 特殊属性

例えば、『自作クラス』に対して vars() が使用できました。『属性名と値の一覧』が辞書として確認できて、便利でした。

(Python) インスタンスオブジェクト

そのほか、『logging モジュールで取得したロガーの設定』を確認するときにも、vars() 関数が便利でした。『ロガーの名前、ロギングレベルの設定、propagate 属性の設定、ロガーに設定したハンドラのリスト』などの状況が、簡単に確認できました。

以上です。

⇒ 【Python】ロガーでロギングするコード例【logging】

⇒ 【Python】multiprocessing.Pool() の使い方【並列処理】

⇒ 【Python】concurrent.futures の使い方【並列処理】

スポンサーリンク
シェアする(押すとSNS投稿用の『編集ページ』に移動します)
フォローする(RSSフィードに移動します)
スポンサーリンク
シラベルノート
タイトルとURLをコピーしました