Python 为什么是';扩展的Iterable解包';不适用于空字符串?

Python 为什么是';扩展的Iterable解包';不适用于空字符串?,python,python-3.x,iterable-unpacking,Python,Python 3.x,Iterable Unpacking,为什么 不可能,什么时候 >>> a, *b = '' 及 因为指定了一个强制变量 右侧应至少有一项(一个字符表示字符串) 根据: 简单赋值(解包)左侧的元组(或列表) 未为扩充分配定义)最多可包含一个 表达式前面有一个星号(从今以后为 称为“带星号”表达式,,而列表中的其他表达式 被称为“强制性的”)。这将指定一个子表达式,该子表达式将 为要解包的iTable中的所有项目分配了一个列表 未分配给任何强制表达式,或者如果 没有这样的项目 基于: ceval.c中的函数un

为什么

不可能,什么时候

>>> a, *b = '' 

因为指定了一个强制变量

右侧应至少有一项(一个字符表示字符串)


根据:

简单赋值(解包)左侧的元组(或列表) 未为扩充分配定义)最多可包含一个 表达式前面有一个星号(从今以后为 称为“带星号”表达式,,而列表中的其他表达式 被称为“强制性的”)。这将指定一个子表达式,该子表达式将 为要解包的iTable中的所有项目分配了一个列表 未分配给任何强制表达式,或者如果 没有这样的项目

基于:

ceval.c
中的函数
unpack_iterable()
通过argcntfeater参数更改为处理扩展的解包。在UNPACK_EX情况下,函数将执行以下操作:

  • 在星号目标之前收集强制性目标的所有项目
  • 从列表中的iterable中收集pop项的所有剩余项
  • 强制目标后,从列表中的星号一推单 项目和堆栈上已调整大小的列表
所以它将在第一步失败,因为字符串中没有强制目标

有关更多信息,请查看
caval.c
中的
unpack\u iterable

>>> a, *b = ''
>>> a, b  # a could == ''
('', [])
unpack_iterable(PyObject*v,int-argcnt,int-argcntfeater,PyObject**sp)
{
int i=0,j=0;
Py_ssize_t ll=0;
PyObject*it;/*iter(v)*/
PyObject*w;
PyObject*l=NULL;/*变量列表*/
断言(v!=NULL);
it=PyObject_GetIter(v);
if(it==NULL)
转到错误;
对于(;i0;j--,i++){
*--sp=PyList_GET_项目(l,ll-j);
}
/*调整列表的大小*/
Py_尺寸(l)=ll-argcntafter;
Py_DECREF(it);
返回1;
错误:
对于(;i>0;i--,sp++)
Py_DECREF(*sp);
Py_XDECREF(it);
返回0;
}

与中的相同区别:
a,*b=[]
(空列表导致错误)和
a,*b=[None]
(应该可以工作)。对于任何空序列,它都会失败。这是非常有意义的,但我认为我只是希望它更像蟒蛇
>>> type('')
<class 'str'>
>>> a, *b = ''
>>> a, b  # a could == ''
('', [])
unpack_iterable(PyObject *v, int argcnt, int argcntafter, PyObject **sp)
{
    int i = 0, j = 0;
    Py_ssize_t ll = 0;
    PyObject *it;  /* iter(v) */
    PyObject *w;
    PyObject *l = NULL; /* variable list */

    assert(v != NULL);

    it = PyObject_GetIter(v);
    if (it == NULL)
        goto Error;

    for (; i < argcnt; i++) {
        w = PyIter_Next(it);
        if (w == NULL) {
            /* Iterator done, via error or exhaustion. */
            if (!PyErr_Occurred()) {
                if (argcntafter == -1) {
                    PyErr_Format(PyExc_ValueError,
                        "not enough values to unpack (expected %d, got %d)",
                        argcnt, i);
                }
                else {
                    PyErr_Format(PyExc_ValueError,
                        "not enough values to unpack "
                        "(expected at least %d, got %d)",
                        argcnt + argcntafter, i);
                }
            }
            goto Error;
        }
        *--sp = w;
    }

    if (argcntafter == -1) {
        /* We better have exhausted the iterator now. */
        w = PyIter_Next(it);
        if (w == NULL) {
            if (PyErr_Occurred())
                goto Error;
            Py_DECREF(it);
            return 1;
        }
        Py_DECREF(w);
        PyErr_Format(PyExc_ValueError,
            "too many values to unpack (expected %d)",
            argcnt);
        goto Error;
    }

    l = PySequence_List(it);
    if (l == NULL)
        goto Error;
    *--sp = l;
    i++;

    ll = PyList_GET_SIZE(l);
    if (ll < argcntafter) {
        PyErr_Format(PyExc_ValueError,
            "not enough values to unpack (expected at least %d, got %zd)",
            argcnt + argcntafter, argcnt + ll);
        goto Error;
    }

    /* Pop the "after-variable" args off the list. */
    for (j = argcntafter; j > 0; j--, i++) {
        *--sp = PyList_GET_ITEM(l, ll - j);
    }
    /* Resize the list. */
    Py_SIZE(l) = ll - argcntafter;
    Py_DECREF(it);
    return 1;

Error:
    for (; i > 0; i--, sp++)
        Py_DECREF(*sp);
    Py_XDECREF(it);
    return 0;
}