Как сделать так, чтобы класс в Python поддерживал __getitem__, но не разрешал итерацию? - PullRequest
3 голосов
/ 29 мая 2009

Я хочу определить класс, который поддерживает __getitem__, но не допускает итерации. например:

class B:
   def __getitem__(self, k):
      return k

cb = B()

for x in cb:
   print x

Что я могу добавить к классу B, чтобы заставить for x in cb: потерпеть неудачу?

Ответы [ 2 ]

14 голосов
/ 29 мая 2009

Я думаю, что несколько лучшим решением было бы повышение TypeError, а не простое исключение (это то, что обычно происходит с не повторяемым классом:

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__)

Тестирование:

>>> 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
2 голосов
/ 29 мая 2009

Из ответов на этот вопрос мы видим, что __iter__ будет вызываться перед __getitem__, если он существует, поэтому просто определите B как:

class B:
   def __getitem__(self, k):
      return k

   def __iter__(self):
      raise Exception("This class is not iterable")

Тогда:

cb = B()
for x in cb: # this will throw an exception when __iter__ is called.
  print x
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...