Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between get and dunder getitem [duplicate]

I am reading Fluent Python and trying to get a deeper understanding of dictionaries.

So when I run the below, the results are easy to understand in that both get() and dunder getitem() return the same result

sample = {'a':1, 'b':2}
print(sample.__getitem__('a')) # 1
print(sample.get('a')) # 1

When I subclass dict with get(), I get a working instance

class MyDict(dict):
    def __missing__(self, key):
        return 0

    def get(self, key):
        return self[key]

d = MyDict(sample)
print(d['a']) # 1
print(d['c']) # 0

Now if I replace get() with dunder getitem() I get an error and I am unsure why.

class MyDict2(dict):
    def __missing__(self, key):
        return 0

    def __getitem__(self, key):
        return self[key]

d = MyDict2(sample)
print(d['a'])
print(d['c'])

error

RecursionError: maximum recursion depth exceeded while calling a Python object

So the question is, what is the difference between get and dunder getitem in this situation and why does this cause a recursion error?

like image 792
bvmcode Avatar asked May 29 '18 13:05

bvmcode


People also ask

What is the __ Getitem __ in Python?

__getitem__ method is used to get an item from the invoked instances' attribute. __getitem__ is commonly used with containers like list, tuple, etc. __setitem__ method is used to set the item into a specific index of the invoked instances' attribute.

What is self __ dict __ Python?

__dict__ is A dictionary or other mapping object used to store an object's (writable) attributes. Or speaking in simple words every object in python has an attribute which is denoted by __dict__. And this object contains all attributes defined for the object.

How does Setitem work in Python?

__setitem__ is a method used for assigning a value to an item. It is implicitly invoked when we set a value to an item of a list, dictionary, etc. __getitem__ is a method used for getting the value of an item. It is implicitly invoked when we access the items of a list, dictionary, etc.


2 Answers

in

def __getitem__(self, key):
    return self[key]

self[key] calls the lowest-level __getitem__ which calls self[key] ... infinite recursion.

In:

def get(self, key):
    return self[key]

self[key] calls the lowest-level __getitem__ as well but from the dict class, so it doesn't recurse: it works (you just overloaded the get method, that's all)

like image 117
Jean-François Fabre Avatar answered Sep 18 '22 20:09

Jean-François Fabre


That is because self[key] in MyDict2.__getitem__(key) is equivalent to (i.e., calls) self.__getitem__(key) => infinite recursion.

like image 29
AGN Gazer Avatar answered Sep 19 '22 20:09

AGN Gazer