Bentley4
Bentley4

Reputation: 11008

How do you define dictionary-like value assignment for a user defined object?

The following code creates a simple gui using the Tkinter module.

import Tkinter

root = Tkinter.Tk()

myContainer1 = Tkinter.Frame(root)
myContainer1.pack()

button1 = Tkinter.Button(myContainer1) 
button1["text"]= "Hello, World!"  
button1["background"] = "green"     
button1.pack()                 

root.mainloop()

Now look at the following bit of code:

button1["text"]= "Hello, World!"

This syntax looks the same as assigning a value to a dictionary key. How do you define the possibility for this behavior for user defined objects? Could you please show with an example such as:

class Example(object):
    def __init__(self, length = 1, width= 2):
        self.length = length
        self.width = width

Edit 1(response to kindall and jsbueno): I'm trying to call the value 42 assigned to e["alpha"] by doing:

print e["alpha"]

To your code I added:

def __getitem__(self, key, value):
    if key in self.validkeys:
        getattr(self, key, value)
    else:
        raise KeyError

But I still get the 'Example' is not subscriptable TypeError.


Edit 2

def __getitem__(self, key):
    if key in self.validkeys:
        return getattr(self, key)
    else:
        raise KeyError

Upvotes: 1

Views: 143

Answers (1)

kindall
kindall

Reputation: 184091

Define __setitem__(); see here. There is a corresponding __getitem__() as well.

As for an example:

class Example(object):
    # define which names can be assigned using [...] syntax
    validkeys = set("alpha beta gamma".split())

    # assign valid names as attributes on our object
    def __setitem__(self, key, value):
        if key in self.validkeys:
            setattr(self, key, value)
        else:
            raise KeyError("Key must be one of %s", ", ".join(self.validkeys))

e = Example()
e["alpha"] = 42
print(e.alpha)   # prints 42

Check the full documentation for emulating dictionaries and other built-in types at: http://docs.python.org/reference/datamodel.html

Upvotes: 5

Related Questions