This is driving me insane. Below is a class
I was messing around with, the goal was to have a way to support dynamic attribute assignment. Please forget for a moment the poor implementation or why I didn't just use a dictionary, I know there are other ways to do this (such as Enum
) but this was my test code before and now it became my quest to find out why it's not working.
class Family(object):
def children(self):
return self.__dict__.values()
def __setitem__(self, key, value):
self.__dict__[key] = value
def __getitem__(self, item):
return self.__dict__[item]
def __repr__(self):
return str(self.__dict__)
def __iter__(self):
return self.__dict__.items()
This all seems fine, and I initiated a test object as follows:
foo = Family()
foo.a = 'foo'
foo.b = 'bar'
[i for i in foo]
Now the expected outcome was [('a', 'foo'), ('b', 'bar')]
, but what I got was this instead:
TypeError: iter() returned non-iterator of type 'dict_items'
I thought I might have messed up the __iter__
method, so I checked as follow:
type(foo.__iter__())
# <class 'dict_items'>
type(foo.__dict__.items())
# <class 'dict_items'>
[i for i in foo.__dict.__items()]
# [('a', 'foo'), ('b', 'bar')]
foo.__dict__.items() == foo.__iter__()
# True
If they're both identical, why doesn't [i for i in foo]
work?
What about this:
def __iter__(self):
return iter(self.__dict__.items())
Python wants an iterator
, not a list
(or other list-like/dict-like object)
Remember: a list
or dict
is not an iterator
, an iterator
is usually (for easy-understanding) a pointer (cursor) pointing to an item of the list
or dict
.
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