I have a class that is a subclass of 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')
A 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 records with underscored keys while iteration.
# data is Result()
>>> for item in data:
>>> print(item)
'description'
'calories'
'name'
'price'
How can I achieve that?
UPDATE: Besides of correct answer I have also overrided keys() and items() methods to hide underscore keys even if this methods will be used in 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']]
Specifically, you may be interested in making custom dictionaries with modified behavior, new functionalities, or both. In Python, you can do this by inheriting from an abstract base class, by subclassing the built-in dict class directly, or by inheriting from UserDict. Create dictionary-like classes by inheriting from the built-in dict class
If you’re making a variation of list or dict and need to customize just a little bit of core functionality, consider inheriting from collections.UserList or collections.UserDict. In general, if you’re making something custom, you’ll often want to reach for the abstract base classes in collections.abc .
Unlike dict, these update and setdefault methods will call our __setitem__ method and the pop and clear methods will call our __delitem__ method. Abstract base classes might make you think we’re leaving the wonderful land of Python duck typing behind for some sort of strongly-typed OOP land. But abstract base classes actually enhance duck typing.
This is indeed a really helpful post! I think an important contributing factor why subclassing built-in types is so unsatisfying is that originally python didn't support subclassing built-in types at all!
Just implement __iter__
. It's important to use .keys()
, in order 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 iteration:
>>> r=Result({1:1,"_foo":2, "bar":3})
>>> for item in r:
... print(item)
...
1
bar
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With