[英]Why is 'Extended Iterable Unpacking' not working for empty strings?
Why is为什么是
>>> a, *b = ''
not possible, when不可能,当
>>> a, *b = ' '
>>> a, b
(' ', []) # b == empty list here anyway.
and和
>>> type('')
<class 'str'>
I mean, why isn't it我的意思是,为什么不是
>>> a, *b = ''
>>> a, b # a could == ''
('', [])
Because there is one mandatory variable specified.因为指定了一个强制变量。
The right side should have at least one item (one character for string).右侧应该至少有一项(字符串一个字符)。
According to PEP-3131 :根据PEP-3131 :
A tuple (or list) on the left side of a simple assignment (unpacking is not defined for augmented assignment) may contain at most one expression prepended with a single asterisk (which is henceforth called a "starred" expression, while the other expressions in the list are called "mandatory" ).
简单赋值左侧的元组(或列表)(未为扩充赋值定义解包)最多可以包含一个带有单个星号的表达式(此后称为“加星号”表达式,而其他表达式在该列表称为“强制性” )。 This designates a subexpression that will be assigned a list of all items from the iterable being unpacked that are not assigned to any of the mandatory expressions, or an empty list if there are no such items.
这指定了一个子表达式,该子表达式将被分配一个列表,该列表包含未分配给任何强制表达式的可迭代对象的所有项目,如果没有此类项目,则为空列表。
Based on PEP 3132 :基于PEP 3132 :
The function
unpack_iterable()
inceval.c
is changed to handle the extended unpacking, via an argcntafter parameter.功能
unpack_iterable()
在ceval.c
被改变来处理扩展拆包,经由argcntafter参数。 In the UNPACK_EX case, the function will do the following:在 UNPACK_EX 情况下,该函数将执行以下操作:
So it will failed in first step because there is no mandatory targets in your string.所以它会在第一步失败,因为你的字符串中没有强制目标。
For more info you can check unpack_iterable
in caval.c
:欲了解更多信息,您可以检查
unpack_iterable
在caval.c
:
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.