在Python 3中有办法继承生成器吗?

6 投票
2 回答
670 浏览
提问于 2025-05-01 13:34

除了明显的原因,我想试试这个,万一有用呢:

def somegen(input=None):
    ...
    yield
    ...

gentype = type(somegen())
class subgen(gentype):
    def best_function_ever():
        ...

可惜,Python的反应非常不友好:

"TypeError: Type generator is not an acceptable base type"

运气不好,这对我来说是个问题。你看,我本来想,也许如果给它一个机会,它会是个有趣的基础类型。想象一下我的惊讶!还有失望。难道就没有办法让强大的Python理解我的想法吗?

这绝对是个非常独特的问题,所以如果你一时想不到办法,请不要直接说不可能。Python(特别是Python 3)是非常灵活的。

当然,如果你有理由证明为什么它不能(而不是“应该不”)成为一个基础类型(Python 3),那么我确实想看看并理解这个理由。

暂无标签

2 个回答

2

另一个相关的问题是 哪些类不能被继承?

在那里的接受答案中,第二个理由是——要实现一个类型的继承,必须在C语言中进行,而生成器的继承没有被实现,可能是因为没有人觉得有这个需求。

生成器对象的源代码在 genobject.c,你可以看到第349行没有设置 Py_TPFLAGS_BASETYPE 标志。

1

你不能直接从一个用 yield 定义的生成器函数去继承(也就是创建一个新的生成器),但是你可以在另一个生成器中使用它。

来看一个简单的例子:

def alphagen(n=27):
    if n<0 or n > 27: n = 27
    for i in range(n):
        yield chr(ord('A') + i)

你会得到:

>>>> [ a for a in alphagen(10)]
['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']

你可以在下面这个地方使用它:

def alphastartgen(n=27):
    resul = ""
    for i in alphagen(n):
        resul += i
        yield resul

现在你得到的是:

>>> [ a for a in alphastartgen(8) ]
['A', 'AB', 'ABC', 'ABCD', 'ABCDE', 'ABCDEF', 'ABCDEFG', 'ABCDEFGH']

撰写回答