Pythonで属性の一覧の取得と属性のフィルタリング。他、関連技術
- 作成日: 2023-06-26
- 更新日: 2023-12-24
- カテゴリ: Python
Pythonで属性の一覧の取得
Pythonでオブジェクトなどの属性の一覧を取得するにはdir()
関数を使います。
dir()
の第1引数にオブジェクトを指定するとリストで属性の文字列が返ってきます。
class Animal:
def __init__(self):
self.age = 20
self.name = 'Tama'
def walk(self):
print('walking...')
print(dir(Animal))
# ['__class__', '__delattr__', '__dict__', '__dir__',
# '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
# '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__',
# '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
# '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
# '__subclasshook__', '__weakref__', 'walk']
animal = Animal()
print(dir(animal))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
# '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
# '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__',
# '__module__', '__ne__', '__new__', '__reduce__',
# '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__',
# '__subclasshook__', '__weakref__', 'age', 'name', 'walk']
上記は独自クラスのAnimal
をdir()
で見た場合です。
dir(Animal)
でクラスの属性を取得しています。このときself.age
やself.name
はありません。
これはこれらの属性が__init__()
で代入されるからです。
animal = Animal()
でAnimal
をオブジェクトにしてdir(animal)
で属性の一覧を取得しています。
こちらにはage
とname
があります。これはオブジェクト化のさいに__init__()
が呼ばれてself.age
とself.name
が代入されたからです。
属性の有無の判定
dir()
が返すのは文字列のリストなのでin
演算子を使えば特定の属性の有無は判定できます。
class Animal:
def __init__(self):
self.age = 20
self.name = 'Tama'
def walk(self):
print('walking...')
print('age' in dir(Animal))
# False
animal = Animal()
print('age' in dir(animal))
# True
しかしPythonにはhasattr()
関数があり、これを使えばもっと簡単に属性の有無を判定できます。
class Animal:
def __init__(self):
self.age = 20
self.name = 'Tama'
def walk(self):
print('walking...')
print(hasattr(Animal, 'age'))
# False
animal = Animal()
print(hasattr(animal, 'age'))
# True
属性のフィルタリング
「__
」で始まる属性を除外するフィルタリングは以下のように行います。
class Animal:
def __init__(self):
self.age = 20
self.name = 'Tama'
def walk(self):
print('walking...')
animal = Animal()
attrs = [attr for attr in dir(animal) if not attr.startswith('__')]
print(attrs)
# ['age', 'name', 'walk']
リスト内包表記でdir(animal)
の結果を回しています。
リスト内包表記は
リスト = [格納したい要素 for 要素 in リストなど]
という感じの表記です。
これはfor
文を簡略化した表記になっています。
上記の場合はリストなどから要素が1つずつ回り、それを格納したい要素に書くことで新しいリストに要素が格納されます。
この格納したい要素に条件を加えたい場合は
リスト = [格納したい要素 for 要素 in リストなど if 条件式]
という感じでお尻にif
を加えます。
🦝 < すげー表記方法だ
🦝 < 溜息が出るな
この条件にif not attr.startswith('__')
と書いています。
startswith()
は文字列のメソッドで、これは文字列の先頭が引数と同じかどうか判定します。
つまり文字列の先頭が__
だったらTrue
を返します。これをnot
で反転していますので、このif
文の条件は「文字列の先頭が__
じゃなかったらTrue
」という条件になります。
True
の場合は「格納したい要素」が新しいリストに格納されるので、これによって__
がついている属性は除外されます。
複数のメソッドをまとめて呼び出し
クラスにメソッドが複数定義されていて、それを一括で呼び出したい場合などは属性の一覧を使った方法が使えます。
class Animal:
def walk(self):
print('walking...')
def run(self):
print('running...')
def dance(self):
print('dancing...')
animal = Animal()
# __が付いている属性を除外
attrs = [attr for attr in dir(animal) if not attr.startswith('__')]
# メソッドの属性をfor文ですべて呼び出し
for attr in attrs:
method = getattr(animal, attr) # 属性の実体を取得
method()
# dancing...
# running...
# walking...
まず__
が付いている属性をdir()
とリスト内包表記で除外します。
こうするとメソッドを抽出できます。もっともインスタンス変数も取得できますのでこの辺はまた別で除外する必要があります。
あとはこの除外した結果のattrs
をfor
文で回してgetattr()
関数でanimal
から属性の実体を取り出します。
getattr()
関数は第1引数のオブジェクトから第2引数の属性の実体を取り出す関数です。
これで取り出したmethod
を実行すればwalk()
, run()
, dance()
のメソッドを一括で呼び出せます。
🦝 < トリッキーですね
🦝 < せやな
おわりに
今回はPythonの属性の一覧の取得と関連技術を解説しました。
なにか参考になれば幸いです。
🦝 < 属性をまとめてゲット!
🦝 < フィルタリングしてシュート!