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

Jul*_*enD 13 python generator typeerror

为什么以下Python代码会引发错误
TypeError: type object argument after * must be a sequence, not generator
,如果我在生成器f中注释第一行(无用),一切正常?

from itertools import izip

def z():
    for _ in range(10): 
        yield _

def f(z):
    for _ in z: pass    # if I comment this line it works! (??)
    for x in range(10):
        yield (x,10*x,100*x,1000*x)

iterators =  izip(*f(z))
for it in iterators:
    print list(it)
Run Code Online (Sandbox Code Playgroud)

注意我实际上要做的是,使用单个生成器,返回多个迭代器(尽可能多的我将作为参数传递给生成器).我发现这样做的唯一方法是产生元组并对它们使用izip() - 对我来说是黑魔法.

Pav*_*sov 27

这很有趣:z当你把它传递给时你忘了打电话f:

iterators =  izip(*f(z()))
Run Code Online (Sandbox Code Playgroud)

所以f试图迭代一个函数对象:

for _ in z: pass  # z is a function
Run Code Online (Sandbox Code Playgroud)

这引发了一个TypeError:

TypeError: 'function' object is not iterable
Run Code Online (Sandbox Code Playgroud)

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);
 ...
Run Code Online (Sandbox Code Playgroud)