Reputation: 13508
I want to define a class that supports __getitem__
, but does not allow iteration.
for example:
class B:
def __getitem__(self, k):
return k
cb = B()
for x in cb:
print x
What could I add to the class B
to force the for x in cb:
to fail?
Upvotes: 3
Views: 2034
Reputation: 13508
From the answers to this question, we can see that __iter__ will be called before __getitem__ if it exists, so simply define B as:
class B:
def __getitem__(self, k):
return k
def __iter__(self):
raise Exception("This class is not iterable")
Then:
cb = B()
for x in cb: # this will throw an exception when __iter__ is called.
print x
Upvotes: 2
Reputation: 11922
I think a slightly better solution would be to raise a TypeError rather than a plain exception (this is what normally happens with a non-iterable class:
class A(object):
# show what happens with a non-iterable class with no __getitem__
pass
class B(object):
def __getitem__(self, k):
return k
def __iter__(self):
raise TypeError('%r object is not iterable'
% self.__class__.__name__)
Testing:
>>> iter(A())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'A' object is not iterable
>>> iter(B())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "iter.py", line 9, in __iter__
% self.__class__.__name__)
TypeError: 'B' object is not iterable
Upvotes: 14