Question

I took this example from a blog, but I don't understand it.

>>> class Udict:
    def __init__(self, dict=None):
        self.data = {}
        if dict is not None: self.update(dict)
    def update(self, dict=None):
        self.data.update(dict)
        print(self.data)

>>> d = {1:'one', 2:'two'}
>>> g = Udict(d)
{1: 'two', 2: 'two'}
>>> g.data
{1: 'two', 2: 'two'}
>>> c.Udict()
{}
>>> c.update({3: 'three'})
{3: 'three'}
>>> 

I expect a recursive call to obj.update() function until 'RuntimeError: maximum recursion depth exceeded'

But no, the update() function reaches to print(self.data)

self.data.update(dict) is calling to itself method update(), so why it doesn't works like I expect?

Can anyone explain to me why a calling to function itself doesn't enter into an endless loop? The blog with the example doesn't explain it.

Was it helpful?

Solution 3

self.data != self.update

Here self.data is an instance variable which is a dictionary object. Dictionary object has update method. So when you call self.data.update(), it calls the method inside the dictionary:

>>> help(dict.update)
Help on method_descriptor:

update(...)
   D.update(E, **F) -> None.  Update D from dict/iterable E and F.
   If E has a .keys() method, does:     for k in E: D[k] = E[k]
   If E lacks .keys() method, does:     for (k, v) in E: D[k] = v
   In either case, this is followed by: for k in F: D[k] = F[k]
>>>

And self.update is an instance method of class Udict:

So lets re-write your code a little bit:

>>> class Udict:
...     def __init__(self):
...         self.data = dict()
...     def update(self, dic=None):
...         if dic:
...             self.data.update(dic)
...         return self.data
...
>>> d = {1:'one', 2:'two'}
>>> g = Udict()
>>> g.update(d)
{1: 'one', 2: 'two'}

For better practice, please don't call any method from init(), please use init() only for initializing attributes, so in your case you can even initialised dic from the argument like:

>>> class Udict:
...     def __init__(self, dic=None):
...         self.data = dict()
...         if dic:
                self.data.update(dic)

Please let me know if that helps.

OTHER TIPS

It isn't calling itself recursively at all.

It doesn't call self.update within update: it calls the update method of the data dict, which is something else entirely.

When it calls self.data.update, it doesn't enter the same function. It is calling the update function of self.data which is simply a dict. If it calls something like self.update then recursion is happening, perhaps that's what you were thinking.

This does not call Udict.update, but dict.update (not recursive):

self.data.update(dict)

Maybe you misunderstand with self.update(dict).

BTW, don't use dict as a variable name. It shadows builtin function dict.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top