[Tutor] maximum recursion error

Peter Otten __peter__ at web.de
Fri Sep 16 09:10:37 EDT 2016


monikajg at netzero.net wrote:

> 
> Hi:
> Below is code where mistakenly self.var is named the same as function var
> instead of a different name. I know that this is not correct but I was
> experimenting to see what happens. 

> class GetSet():

GetSet is a classic class -- when you use properties with these all bets are 
off.

> 
>     def __init__(self, value):
>         #self.attrval = value
>         self.var = value
> 
>     @property
>     def var(self):
>         print "getting the var attribute. "
>         #return self.attrval
>         return self.var
>     @var.setter
>     def var(self,value):
>         print "setting the var attribute"
>         #self.attrval = value
>         self.var = value
> 
>     @var.deleter
>     def var(self):
>         print "deleting the var attribute. "
>         #self.attrval = None
>         self.var = None
> 
> When I run the code with below I get " maximum recursion depth exceeded
> while calling a Python object" which is what I expected. me = GetSet(5)
> me.var = 1000
> print me.var   - I do not get "max recursion error" here. Why?
> del me.var
> print me.var   - Here I get "max recursion error"
> 
> What I do not understand is why I do not get the same error when runing
> below:
> 
> me = GetSet(5)
> me.var = 1000

This updates the instance dict (called __dict__).

> print me.var

This accesses the instance dict and finds the key "var". When you remove 
that key with 

del me.var

the next access

me.var

will fall back from the instance to the class and thus invoke the getter of 
the var property which itself tries to read me.var and thus causes the 
recursion error. A sample session in the interactive interpreter:

>>> class GetSet:
...     @property
...     def var(self):
...         print "reading var"
...         return self.var
...     @var.setter
...     def var(self, value):
...         print "writing var"
... 
>>> x = GetSet()
>>> x.var = 42
>>> x.__dict__
{'var': 42}
>>> del x.var
>>> x.__dict__
{}
>>> import sys; sys.setrecursionlimit(7)
>>> x.var
reading var
reading var
reading var
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in var
  File "<stdin>", line 5, in var
  File "<stdin>", line 5, in var
RuntimeError: maximum recursion depth exceeded while calling a Python object

To make it crystal clear, classic classes are not intended to work with 
properties -- the support for getters is likely an implementation accident.
Once you switch to newstyle classes sanity is restored, and the setter is no 
longer bypassed:

>>> class GS(GetSet, object): pass
... 
>>> GS().var = 123
writing var


> 
> Why do I get the error after I do del but not without del? Why do I get
> the error after doing print me.var for the second time but not for the
> first time? In my understanding I should get the recursion error after the
> first print me.var. Why do I have to del and print again me.var to get the
> "max recursion error"? Thank you very much Monika




More information about the Tutor mailing list