I want to create the class 'Human' with attributes "name" and "gender". I want to restrict assignment of the "gender" attribute to only "male" or "female". For this purpose, we have overridden __setattr__(self, name, value).
class Human(object):
def __setattr__(self, name, value):
if name == 'gender':
if value in ('male', 'female'):
self.gender = value
else:
raise AttributeError('Gender can only be "male" or "female"')
h = Human()
h.name = 'Sweety'
h.gender = 'female'
print(h.gender)
But I am getting below exception:
[Previous line repeated 328 more times]
File "/Users/admin/algorithms/betright_test.py", line 143, in **__setattr__**
if name == 'gender':
RecursionError: maximum recursion depth exceeded in comparison
But If I pass wrong gender(h.gender = 'f') it gives me proper Error(AttributeError: Gender can only be "male" or "female")
I am not able to figure out that what went wrong when I passed the proper gender.
The problem is that your __setattr__
function contains the line self.gender =
... which calls __setattr__
in an infinite loop. You need to store the attribute without recursively calling __setattr__
by using the superclass method:
super().__setattr__(name, value)
Note also in your example code, if you tried to print h.name, you'd get an AttributeError, as your __setattr__
function never set the attribute. So what you want is something like:
def __setattr__(self, name, value):
if name == 'gender':
if value not in ('male', 'female'):
raise AttributeError('Gender can only be "male" or "female"')
super().__setattr__(name, value)