Python の setattr()
関数は、オブジェクトの名前を指定してその属性を設定するために使用されます。
非常にシンプルな関数ですが、Pythonでのオブジェクト指向プログラミングの文脈では非常に有用であることが分かります。
この関数をPythonのプログラムの中でどのように使うことができるのか見てみましょう。
setattr() 関数のシンタックス
オブジェクト名、属性名、値をパラメータとして受け取り、 object.attribute
を value
と等しくなるように設定します。
オブジェクトの属性はどのような型でもよいので、この関数によって例外が発生することはありません。
以下は、setattr()
の使い方を説明する簡単な例です。
class MyClass():
def __init__(self, name, value):
setattr(self, name, value)
a = MyClass('KEY', 100)
print('a.KEY)
print(getattr(a,'KEY'))
結果は以下の通りです。
100
100
setattr()
は、オブジェクトの属性が事前にわからず、 object.attribute_name = value
で設定できない場合に非常に便利な関数です。
これは非常に便利なメソッドで、オブジェクトの属性が実行中に変更される可能性がある場合に使用され、オブジェクト指向プログラミングがこのようなシナリオでも十分に機能することを示しています。
この記事もチェック:Pythonのmapメソッドの使い方|ラムダ関数や引数が複数の場合の使い方も解説
setattr()とgetattrr()を併用する方法
このメソッドは、一般的に getattr()
メソッドと組み合わせて、オブジェクトの属性を取得したり設定したりするために使用されます。
以下の例では、一人の生徒に対して、オブジェクトを構築し、各科目の属性を対応する点数に設定します。
setattr()
を使用して Student オブジェクトを構築した後、 getattr()
を使用して学生の教科ごとの点数をソートします。
class Student():
def __init__(self, name, results):
self.name = name
for key, value in results.items():
setattr(self, key, value)
def update_mark(self, subject, mark):
self.subject = mark
subjects = ['Physics' ,'Chemistry' ,'Biology' ]
a = Student('Amit', {key: valuefor(key, value)in zip(subjects, [73 , 81 , 90])})
b = Student('Rahul', {key: valuefor(key, value)in zip(subjects, [91 , 89 , 74])})
c = Student('Sunil', {key: valuefor(key, value)in zip(subjects, [59 , 96 , 76])})
student_list = [a, b, c]
stud_names = [student.name for student in student_list]
print('Sorted Physics Marks:')
print(sorted([getattr(s,'Physics')for s instudent_list]))
print('Sorted Marks for all subjects:')
print(sorted([getattr(s, subject)for s in student_list for subject insubjects]))
print('Sorted Marks for every Student:')
print(dict(zip(stud_names, [sorted([getattr(s, subject)for subject insubjects])for s instudent_list])))
Pythonのワンライナーの中には、とても複雑に見えるものもありますが、そうではありません。
最初の sorted([getattr(s, 'Physics') for s in student_list])
は、次のものと同じです。
ls = []
for s instudent_list:
ls.append(getattr(s,'Physics'))
# Sort the list
ls.sort()
print(ls)
2番目のライナーも非常によく似ていますが、1つのループではなく、2つのネストされたループを使用しています。
ls = []
for s in student_list:
for subject in subjects:
ls.append(getattr(s, subject))
ls.sort()
print(ls)
最後のものは少し厄介で、各生徒について name: sorted_subject_marks
の Dictionary を作成します。
まず、それぞれの名前に対して繰り返し処理を行い、生徒オブジェクトのリストから属性を取得し、その中間リストをソートしてからDictionaryに追加しています。
dct = {}
for name, s in zip(subjects, student_list):
ls = []
for subject in subjects:
ls.append(getattr(s, subject))
ls.sort()
dct[name] = ls
print(dct)
結果は以下の通りです。
SortedPhysics Marks:
[ 59 , 73 , 91 ]
Sorted Marks for allsubjects:
[ 59 , 73 , 74 , 76 , 81 , 89 , 90 , 91 , 96 ]
Sorted Marks forevery Student:
{'Amit': [73 , 81 , 90 ],'Rahul': [74 , 89 , 91 ],'Sunil': [59 , 76 , 96 ]}
まとめ
この記事では、オブジェクトの属性を実行時に動的に設定するための setattr()
メソッドについて学びました。
これはオブジェクト指向プログラミングにおいて、開発者が属性を知らない場合に非常に有用なメソッドであり、柔軟なAPIを構築するために使用されます。