繁体   English   中英

Python 3:如何为派生类编写__iter__方法,以便它扩展基类的__iter__方法的行为

[英]Python 3: How to write a __iter__ method for derived class so that it extends on the behaviour of the base class' __iter__ method

说我有一个基类:

class Base:
    A = False
    B = ''
    C = ''

    def __iter__(self):
        yield 'a', self.A
        yield 'b', self.B
        yield 'c', self.C

然后从这个基础派生出一个类:

class Data(Base):
    D = ''

    def __iter__(self):
        yield 'd', self.D

当然,如果将数据类的实例转换为dict类型,则只在dict( Data() )上创建一个包含{ 'd': <value> } dict 因为据我所知,派生类__iter__方法有效地覆盖了基类__iter__方法。

然后,我尝试像在__init__()函数中那样,从派生类覆盖的方法中调用基类方法:

def __iter__(self):
    super().__iter__()
    yield 'd', self.D

但是IDE将其标记为错误。 为什么这不起作用? 以及如何定义派生的iter方法以在已经存在的基类iter方法上扩展,这样我只需要为派生类中添加的变量添加yield即可? 是否在派生类iter方法中再次手动写出所有收益,这是我目前实现的唯一解决方案? 为什么?

class Data(Base):
    D = ''

    def __iter__(self):
        yield 'a', self.A
        yield 'b', self.B
        yield 'c', self.C
        yield 'd', self.D

这将不起作用,因为super().__iter__()是一个生成器,在这种情况下调用生成器没有任何意义。 您想要做的是迭代该生成器返回的内容,并从Data__iter__中产生它们:

Python 2:

def __iter__(self):
    for i in super().__iter__():
        yield i
    yield 'd', self.D

但是在Python 3中,可以更简洁地写为:

def __iter__(self):
    yield from super().__iter__()
    yield 'd', self.D

您必须委托给基类:

In [1]: class Base:
   ...:     A = False
   ...:     B = ''
   ...:     C = ''
   ...:
   ...:     def __iter__(self):
   ...:         yield 'a', self.A
   ...:         yield 'b', self.B
   ...:         yield 'c', self.C
   ...:

In [2]: class Data(Base):
   ...:     D = ''
   ...:
   ...:     def __iter__(self):
   ...:         yield from super().__iter__()
   ...:         yield 'd', self.D
   ...:

In [3]: print(list(Data()))
[('a', False), ('b', ''), ('c', ''), ('d', '')]

In [4]: print(dict(Data()))
{'c': '', 'b': '', 'd': '', 'a': False}

Python 3允许yield from语法中yield from ,在Python 2中使用:

class Base(object): # make sure to inherit from object for super to work
    A = False
    B = ''
    C = ''

    def __iter__(self):
        yield 'a', self.A
        yield 'b', self.B
        yield 'c', self.C

class Data(Base):
    D = ''

    def __iter__(self):
        for x in super(Data, self).__iter__():
            yield x
        yield 'd', self.D

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM