Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override dict() on class

I'm trying to make a dict-like class in Python.

When you make a class, you have certain methods that tell Python how to make a built-in class. For example, overriding the __int__ method tells Python what to return if the user uses int() on an instance of the class. Same for __float__. You can even control how Python would make an iterable object of the class by overriding the __iter__ method (which can help Python make lists and tuples of your class). My question is how would you tell Python how to make a dict of your custom class? There is no special __dict__ method, so how would you go about doing it? I want something like the following:

class Foo():
    def __dict__(self):
        return {
            'this': 'is',
            'a': 'dict'
        }

foo = Foo()
dict(foo) # would return {'this': 'is', 'a': 'dict'}

I've tried making the class inherit from dict, but it raises an error later in the code because of subclasses trying to inherit from dict and type, so inheriting from dict isn't a possibility. Is there any other way to do it?

Also, I've overridden the __iter__ method already so that it would return a dict_keyiterator object (what gets returned when you use iter() on a dict), but it still doesn't seem to work how it should.

like image 556
ChristianFigueroa Avatar asked Oct 08 '17 02:10

ChristianFigueroa


People also ask

How do you override a dictionary in Python?

Actually subclassing dict We can reuse the dict methods through inheritance. All we need to do is create an interface layer that ensures keys are passed into the dict in lowercase form if they are strings. If I override __getitem__ / __setitem__ , then get/set don't work.

Is dict () a method in Python?

Python dict() MethodThe dict() method creates a dictionary object from the specified keys and values, or iterables of keys and values or mapping objects.

What is __ dict __ method?

The __dict__ in Python represents a dictionary or any mapping object that is used to store the attributes of the object. They are also known as mappingproxy objects. To put it simply, every object in Python has an attribute that is denoted by __dict__.

What is dict () function?

The dict() function creates a dictionary. A dictionary is a collection which is unordered, changeable and indexed.


2 Answers

Although the approach in the answer from @ForeverWintr is fairly clever and works, I think it's a little obscure since it takes advantage of some of the arcane details about the attributes of the argument passed to the dict class constructor.

For that reason a better approach might be what I was saying in my comments about just adding a method that does what you want (plus shows how simply giving it a name indicating exactly what's going on makes it more understandable).

Example code:

class Foo:
    def to_dict(self):
        return {'this': 'is', 'more': 'clear'}

print( Foo().to_dict() )  # -> {'this': 'is', 'more': 'clear'}
like image 125
martineau Avatar answered Sep 19 '22 10:09

martineau


dict can be called with an iterable of pairs, so if you design your __iter__ to return an iterable of tuples, your example works as you'd like:

class Foo:
    def __iter__(self):
        yield from {
            'this': 'is',
            'a': 'dict'
        }.items()

dict(Foo())
{'a': 'dict', 'this': 'is'}

If you want your class to behave like a python dictionary, in that iterating over an instance iterates over its keys, you can implement the interface defined by abc.Mapping.

You can do this either by implementing __getitem__, __iter__, and __len__, and inheriting from abc.Mapping, or by implementing all of __getitem__, __iter__, __len__ __contains__, keys, items, values, get, __eq__, and __ne__.

like image 40
ForeverWintr Avatar answered Sep 19 '22 10:09

ForeverWintr