Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inherit a python generator and overwrite __iter__

I want to call the mother class but I get this message :

Traceback (most recent call last):
  File "***test.py", line 23, in <module>
    for i in daughter:
  File "***test.py", line 18, in __iter__
    for i in super(Mother, self):
TypeError: 'super' object is not iterable

I think it's just about the syntax, I try to call super(Mother, self) without any method, just the object itself. Here the code :

class Mother(object):
    def __init__(self, upperBound):
        self.upperBound = upperBound

    def __iter__(self):
        for i in range (self.upperBound):
            yield i


class Daughter(Mother):
    def __init__(self, multiplier, upperBound):
        self.multiplier = multiplier
        super(Daughter, self).__init__(upperBound)

    def __iter__(self):
        for i in super(Mother, self): # Here
            yield i * self.multiplier


daughter = Daughter(2, 4)
for i in daughter:
    print i

Here it's just an exemple, my purpose is to read a file and yield line by line. Then a subclass generator parse all lines (for exemple make a list from the line...).

like image 602
hayj Avatar asked Jun 06 '16 08:06

hayj


People also ask

What is difference between iterator and generator in Python?

Iterators are the objects that use the next() method to get the next value of the sequence. A generator is a function that produces or yields a sequence of values using a yield statement. Classes are used to Implement the iterators. Functions are used to implement the generator.

How do you access the generator object in Python?

You need to call next() or loop through the generator object to access the values produced by the generator expression. When there isn't the next value in the generator object, a StopIteration exception is thrown. A for loop can be used to iterate the generator object.

Is multiple inheritance Pythonic?

Yes, Python supports multiple inheritance. Like C++, a class can be derived from more than one base classes in Python. This is called Multiple Inheritance.

Do Python subclasses inherit methods?

Classes called child classes or subclasses inherit methods and variables from parent classes or base classes.


1 Answers

The proxy object returned by super() is not iterable just because there is an __iter__ method in the MRO. You need to look up such methods explicitly, as only that'll kick of a search:

for i in super(Daughter, self).__iter__():
    yield i * self.multiplier

Note that you need to use super() on the current class, not the parent.

super() can't directly support special methods because these are looked up directly on the type by Python, not the instance. See Special method lookup for new-style classes:

For new-style classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

type(super(Daughter, self)) is the super type object itself, and it doesn't have any special methods.

Demo:

>>> class Mother(object):
...     def __init__(self, upperBound):
...         self.upperBound = upperBound
...     def __iter__(self):
...         for i in range (self.upperBound):
...             yield i
...
>>> class Daughter(Mother):
...     def __init__(self, multiplier, upperBound):
...         self.multiplier = multiplier
...         super(Daughter, self).__init__(upperBound)
...     def __iter__(self):
...         for i in super(Daughter, self).__iter__():
...             yield i * self.multiplier
...
>>> daughter = Daughter(2, 4)
>>> for i in daughter:
...     print i
...
0
2
4
6
like image 63
Martijn Pieters Avatar answered Oct 12 '22 21:10

Martijn Pieters