Python TypeError:在*之后的type对象参数必须是序列,而不是生成器

Python TypeError:在*之后的type对象参数必须是序列,而不是生成器,python,generator,typeerror,Python,Generator,Typeerror,为什么下面的Python代码会引发错误 TypeError:在*之后的type对象参数必须是序列,而不是生成器 如果我对生成器f中的第一行(无用)进行注释,一切正常吗 从itertools导入izip def z(): 对于范围(10)内的uu: 屈服_ 定义f(z): 对于uz:pass 35;如果我对这行进行注释,它会起作用!(??) 对于范围(10)内的x: 产量(x,10*x,100*x,1000*x) 迭代器=izip(*f(z)) 对于迭代器中的它: 打印列表(it) 注意,我实际

为什么下面的Python代码会引发错误
TypeError:在*之后的type对象参数必须是序列,而不是生成器

如果我对生成器f中的第一行(无用)进行注释,一切正常吗

从itertools导入izip
def z():
对于范围(10)内的uu:
屈服_
定义f(z):
对于uz:pass 35;如果我对这行进行注释,它会起作用!(??)
对于范围(10)内的x:
产量(x,10*x,100*x,1000*x)
迭代器=izip(*f(z))
对于迭代器中的它:
打印列表(it)

注意,我实际上要做的是,使用一个生成器,返回多个迭代器(作为参数传递给生成器的迭代器的数量)。我发现的唯一方法是生成元组并对其使用izip(),这对我来说是一种黑魔法。

这很有趣:当你将它传递给
f
时,你忘记调用
z

iterators =  izip(*f(z()))
因此
f
尝试迭代函数对象:

for _ in z: pass  # z is a function
这引发了一个类型错误:

TypeError: 'function' object is not iterable
Python内部捕捉到它,并用一条令人困惑的错误消息重新发出

# ceval.c

static PyObject *
ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk)
{
 ...

            t = PySequence_Tuple(stararg);
            if (t == NULL) {
                if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                    PyErr_Format(PyExc_TypeError,
                                 "%.200s%.200s argument after * "
                                 "must be a sequence, not %200s",
                                 PyEval_GetFuncName(func),
                                 PyEval_GetFuncDesc(func),
                                 stararg->ob_type->tp_name);
 ...

您可能会从itertools中发现
tee
很有趣…
tee
必须运行并存储所有元素一次,然后才能复制迭代器,参见文档:。不幸的是,这里没有魔法,我在这里的尝试很幼稚。看起来它只是最近才修复的。我在一些代码中被这一点咬了一口,这些代码想在一个可以在内部引发TypeError的生成器上使用
zip(*…)
——我已经计划好了这些错误,并打算让它们传播。看起来我现在必须手动构建“压缩”列表,因为我仍然使用3.4:(