Custom iteration behavior in a dict subclass

I have a class that is a subclass of the standard dict:

class Result(dict):

    """ Dict-like object with special methods """

    def content(self):
        return self.__getitem__('_content')

    def attrs(self):
        return self.__getitem__('_attrs')

Sample representation in this object:

{
    '_attrs': {'id': 1},
    'description': 'testtest',
    'calories': 1234,
    '_content': 'Sample content',
    'name': 'qwerty',
    'price': 12390
}

I want my class to skip entries with underlined keys during iteration.

# data is Result()
>>> for item in data:
>>>    print(item)

'description'
'calories'
'name'
'price'

How can i achieve this?

UPDATE: In addition to the correct answer, I also redefined the keys () and items () methods to hide the underscore keys, even if these methods are used in an iteration:

def __iter__(self):
    for key in self.keys():
        yield key

def keys(self):
    return [key for key in super().keys() if key not in ['_attrs', '_content']]

def items(self):
    return [(key, value) for key, value in super().items() if key not in ['_attrs', '_content']]
+4
source share
2 answers

Just install __iter__. It is important to use .keys()to avoid infinite recursion:

class Result(dict):
    def __iter__(self):
        for key in self.keys():
            if not(isinstance(key, str) and key.startswith("_")):
                yield key

Then it will be skipped in an iteration:

>>> r=Result({1:1,"_foo":2, "bar":3})
>>> for item in r:
...     print(item)
...
1
bar
+6
source

startswith.

>>> x = {'_content':3, 'data':5, '_roarr':'chen'}
>>> for i in x.keys():
...     if i.startswith('_'): pass
...     else: print(x[i])
... 
5
0

Source: https://habr.com/ru/post/1627309/


All Articles