代码之家  ›  专栏  ›  技术社区  ›  grieve

在python中,如何使类支持getitem,但不允许迭代?

  •  3
  • grieve  · 技术社区  · 15 年前

    我想定义一个支持 __getitem__ ,但不允许迭代。 例如:

    class B:
       def __getitem__(self, k):
          return k
    
    cb = B()
    
    for x in cb:
       print x
    

    我能给这个班加些什么 B 迫使 for x in cb: 失败?

    2 回复  |  直到 11 年前
        1
  •  14
  •   Rick Copeland    15 年前

    我认为一个稍微好一点的解决方案是引发一个类型错误,而不是一个简单的异常(这是非iterable类通常会发生的情况:

    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
  •  2
  •   Community basarat    7 年前

    从这个问题的答案 question 我们可以看到,如果存在的话,将在getitem之前调用iter,所以简单地将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