The Python Oracle

Getting the return value of __setitem__() and length of dictionary

--------------------------------------------------
Hire the world's top talent on demand or became one of them at Toptal: https://topt.al/25cXVn
and get $2,000 discount on your first invoice
--------------------------------------------------

Music by Eric Matyas
https://www.soundimage.org
Track title: Puzzle Game 5 Looping

--

Chapters
00:00 Getting The Return Value Of __setitem__() And Length Of Dictionary
00:40 Answer 1 Score 1
00:50 Accepted Answer Score 4
01:53 Answer 3 Score 2
02:16 Thank you

--

Full question
https://stackoverflow.com/questions/1968...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python

#avk47



ACCEPTED ANSWER

Score 4


Assignment doesn't have a return value in Python and the return value of __setitem__() is ignored. Generally, you'd want to raise an exception instead:

class Only5Items(dict):

    def __setitem__(self, key, value):
        if len(self) < 5 or key in self:   # allow reassignment of existing key
            return super(Only5Items, self).__setitem__(key, value)
        raise KeyError("maximum number of items (5) exceeded")

Then your client code can catch the exception:

items = Only5Items(hi1="asdf1", hi2="asdf2", hi3="asdf3", hi4="asdf4", hi5="asdf5")
try:
    items["hi6"] = "asdf6"
except KeyError as e:
    print(e)

If you want to return True/False then you have to write your own assignment method that can return a value:

class Only5Items(dict):

    def __setitem__(self, key, value):
        if len(self) < 5 or key in self:   # allow reassignment of existing key
            return super(Only5Items, self).__setitem__(key, value)
        raise KeyError("maximum number of items (5) exceeded")

    def did_set(self, key, value):
        try:
            self[key] = value
        except KeyError:
            return False
        return True

Then you'd use it like this:

if not items.did_set("hi6", "asdf6"):
    print "couldn't set key 'hi6', dictionary is probably full"

You probably also want to override setdefault() to check the number of items too... also, it'd be nice (and pretty easy) to pass in the maximum number when you instantiate the class instead of hard-coding it to 5.




ANSWER 2

Score 2


Erm, I'd just do the following:

class Only5Items(dict):
    def __setitem__(self, key, value):
        if len(self) < 5:
            return super(Only5Items, self).__setitem__(key, value)
        else:
            raise KeyError("You forgot I can only have 5 items dummy!")

    def __str__(self):
        return super(Only5Items, self).__str__()

The following script:

d = Only5Items(a=1, b=2, c=3, d=4, e=5)
print d

try:
    d['making a mistake'] = 'hahahahah'
except KeyError, e:
    print e

Produces:

{'a': 1, 'c': 3, 'b': 2, 'e': 5, 'd': 4}
'You forgot I can only have 5 items dummy!'



ANSWER 3

Score 1


class Only5Items(dict):
    def __setitem__(self, key, value):
        if len(self) < 5:
            super(Only5Items, self).__setitem__(key, value)
            print "Succesfully inserted!"
        else:
            print "Dictionary full!"