在python中子类化和覆盖生成器函数

ejm*_*ejm 15 python python-3.x

我需要覆盖父类的方法,它是一个生成器,我想知道正确的方法来做到这一点.以下是否有任何问题,或更有效的方法?

class A:
    def gen(self):
        yield 1
        yield 2

class B(A):
    def gen(self):
        yield 3
        for n in super().gen():
            yield n
Run Code Online (Sandbox Code Playgroud)

Mic*_*ber 8

你有什么看起来很好,但不是唯一的方法.生成器函数的重要之处在于它返回一个可迭代对象.因此,您的子类可以直接创建一个iterable,例如:

import itertools

class B(A):
    def gen(self):
        return itertools.chain([3], super().gen())
Run Code Online (Sandbox Code Playgroud)

更好的方法取决于你正在做什么; 以上看起来不必要复杂,但我不想从这样一个简单的例子中概括出来.

  • @eyquem问题中使用的语法和我的答案是Python 3.在Python 3中没有经典类,所以`class A`相当于`class A(object)`. (3认同)

Sha*_*ger 7

对于Python 3.3及更高版本,最好,最常用的方法是:

class A:
    def gen(self):
        yield 1
        yield 2

class B(A):
    def gen(self):
        yield 3
        yield from super().gen()
Run Code Online (Sandbox Code Playgroud)

这使用yield from语法委托给子生成器.它比其他解决方案更好,因为它实际上是将控制权交给它所委托的发电机; 如果所述生成器支持.send并将.throw值和异常传递生成器中,则委托意味着它实际接收值; 显式循环和yield逐个循环将接收gen包装器中的值,而不是实际生成值的生成器,同样的问题适用于其他解决方案,如使用itertools.chain.