1

I'm trying to alter the __iter__ method on a Python class instance. It seems like a straightforward operation:

from __future__ import print_function

class A(object):
    def __iter__(self):
        yield 'i'
        yield 'am'
        yield 'A'

    def newIter(self):
        yield 'i'
        yield 'am'
        yield 'new'

    def changeIter(self):
        self.__iter__ = self.newIter

a = A()
a.changeIter()

print(a.__iter__)
print(list(a))

However, in both CPython 2.7.2 and 3.4.1 this prints:

<bound method A.newIter of <__main__.A object at 0x10317ecd0>>
['i', 'am', 'A']

The first print seems to confirm that a.__iter__ has indeed been changed. So why is the new function not called? The above works fine for regular methods, so I guess __iter__ is special in some way (at least in CPython), but how/why?

Thanks for any help!

terrycojones
  • 197
  • 2
  • 6
  • 2
    Yes, it is a [special method](https://docs.python.org/3/reference/datamodel.html#specialnames) and special methods are always looked up in the class not instance. – Ashwini Chaudhary Aug 09 '14 at 22:01
  • @AshwiniChaudhary - That sounds like an answer. – Robᵩ Aug 09 '14 at 22:05
  • Thanks @AshwiniChaudhary I guess I'm just going to have to define my own `iter` for my classes. I don't find the reasoning in https://docs.python.org/3/reference/datamodel.html#special-method-lookup very convincing. Anyway.... – terrycojones Aug 09 '14 at 22:14

0 Answers0