RecursionError when using @property decorator
Question:
I am learning the @property manipulation and writing some codes as below, while the cmd just shows,
Traceback (most recent call last):
File "C:Usersmckf1pyfilenew.py", line 23, in <module>
s.width=1024
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
[Previous line repeated 495 more times]
RecursionError: maximum recursion depth exceeded
However, after I add one lower dash in front of the arguments (width, height, resolution), the codes fuction normally. I don’t understand why.
class Screen(object):
@property
def width(self):
return self.width
@width.setter
def width(self,value1):
if value1<=10 or value1>=10000:
print(value1,'is not a proper width')
else:
self.width=value1
@property
def height(self):
return self.height
@height.setter
def height(self,value2):
if value2<=5 or value2>=5000:
print(value2,'is not a proper height')
else:
self.height=value2
@property
def resolution(self):
self.resolution=self.width*self.height
print(self.width,'*',self.height,'= %d'%self.resolution)
s=Screen()
s.width=1024
s.height=768
s.resolution
Answers:
Decorators are not ignored when accessing the property from within the class. So when the width()
method does
return self.width
that invokes the width()
method again, which tries to return self.width
, which invokes the method, and so on and so one.
This is why you need to use different names for the properties internally to the class than the names of the decorator methods.
@property
def width(self):
return self._width
Accessing the _width
property doesn’t try to use the decorated method, so you don’t get into an infinite recursion.
I am learning the @property manipulation and writing some codes as below, while the cmd just shows,
Traceback (most recent call last):
File "C:Usersmckf1pyfilenew.py", line 23, in <module>
s.width=1024
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
File "C:Usersmckf1pyfilenew.py", line 9, in width
self.width=value1
[Previous line repeated 495 more times]
RecursionError: maximum recursion depth exceeded
However, after I add one lower dash in front of the arguments (width, height, resolution), the codes fuction normally. I don’t understand why.
class Screen(object):
@property
def width(self):
return self.width
@width.setter
def width(self,value1):
if value1<=10 or value1>=10000:
print(value1,'is not a proper width')
else:
self.width=value1
@property
def height(self):
return self.height
@height.setter
def height(self,value2):
if value2<=5 or value2>=5000:
print(value2,'is not a proper height')
else:
self.height=value2
@property
def resolution(self):
self.resolution=self.width*self.height
print(self.width,'*',self.height,'= %d'%self.resolution)
s=Screen()
s.width=1024
s.height=768
s.resolution
Decorators are not ignored when accessing the property from within the class. So when the width()
method does
return self.width
that invokes the width()
method again, which tries to return self.width
, which invokes the method, and so on and so one.
This is why you need to use different names for the properties internally to the class than the names of the decorator methods.
@property
def width(self):
return self._width
Accessing the _width
property doesn’t try to use the decorated method, so you don’t get into an infinite recursion.