Python setattr() Function

Python setattr() function is used to set the attribute of an object, given its name. While being a very simple function, it can prove to be very useful in the context of Object Oriented Programming in Python. Let us look at how we could use this function in our Python programs.


setattr() Function Syntax

It takes the object name, the attribute name and the value as the parameters, and sets object.attribute to be equal to value. Since any object attribute can be of any type, no exception is raised by this function.

Format: setattr(object, attr, value)

Here is a simple example to demonstrate the use of setattr().

class MyClass():
    def __init__(self, name, value):
        # Set the attribute of the class object
        setattr(self, name, value)

a = MyClass('KEY', 100)
print('Printing attribute from Class Object:', a.KEY)
print('Printing attribute from getattr():', getattr(a, 'KEY'))

Output

Printing attribute from Class Object: 100
Printing attribute from getattr(): 100

setattr() is very useful when the attribute of the object is not know beforehand, and cannot be set using object.attribute_name = value.

This is a very handy method, used whenever the attributes of the object can change during runtime, and demonstrates how Object Oriented Programming still performs well in these scenarios.


Using setattr() with getattrr()

It is commonly used in tandem with the getattr() method, to get and set the attributes of Objects.

Here is an example to demonstrate some of the use-cases of setattr(), when paired with the getattr() method.

This example constructs objects and sets the attributes of each subject to their corresponding marks, for a single student.

After constructing the Student object using setattr(), we use getattr() and sort the subject-wise marks of students.

class Student():
	def __init__(self, name, results):
		self.name = name
		for key, value in results.items():
                        # Sets the attribute of the 'subject' to
                        # the corresponding subject mark.
                        # For example: a.'Chemistry' = 75
			setattr(self, key, value)

	def update_mark(self, subject, mark):
		self.subject = mark


subjects = ['Physics', 'Chemistry', 'Biology']

a = Student('Amit', {key: value for (key, value) in zip(subjects, [73, 81, 90])})

b = Student('Rahul', {key: value for (key, value) in zip(subjects, [91, 89, 74])})

c = Student('Sunil', {key: value for (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 in student_list]))

print('\nSorted Marks for all subjects:')
print(sorted([getattr(s, subject) for s in student_list for subject in subjects]))

print('\nSorted Marks for every Student:')
print(dict(zip(stud_names, [sorted([getattr(s, subject) for subject in subjects]) for s in student_list])))

While some of the Python one-liners may seem very complicated, it is not. The first one sorted([getattr(s, 'Physics') for s in student_list]) is equivalent to:

ls = []
for s in student_list:
    ls.append(getattr(s, 'Physics'))
# Sort the list
ls.sort()
print(ls)

The second one liner is also extremely similar, but using two nested loops instead of one.

ls = []
for s in student_list:
    for subject in subjects:
        ls.append(getattr(s, subject))
ls.sort()
print(ls)

The last one is a bit tricky, wherein you construct a Dictionary of name: sorted_subject_marks for each student.

We first iterate through each name and get the attribute from the student object list, and then sort the intermediate list, before adding to our 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)

Output of the complete code snippet:

Sorted Physics Marks:
[59, 73, 91]

Sorted Marks for all subjects:
[59, 73, 74, 76, 81, 89, 90, 91, 96]

Sorted Marks for every Student:
{'Amit': [73, 81, 90], 'Rahul': [74, 89, 91], 'Sunil': [59, 76, 96]}

Conclusion

In this article, we learned about the setattr() method, which is used to dynamically set the object attributes at runtime. This is a very useful method for Object Oriented Programming, when the attributes are not known to the developer, and is thus used for building flexible API.

References