为什么分配给空列表有效而不分配给空元组? [英] Why is it valid to assign to an empty list but not to an empty tuple?

查看:41
本文介绍了为什么分配给空列表有效而不分配给空元组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是在 最近的 PyCon 演讲中提出的.

声明

[] = []

没有做任何有意义的事情,但它也不会抛出异常.我觉得这一定是由于拆包规则造成的.您也可以使用列表进行元组解包,例如,>

[a, b] = [1, 2]

做你所期望的.作为合乎逻辑的结果,当要解包的元素数为 0 时,这也应该有效,这将解释为什么分配给空列表是有效的.当您尝试将非空列表分配给空列表时会发生什么,进一步支持了这一理论:

<预><代码>>>>[] = [1]回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中ValueError:解包的值太多

如果元组也是如此,我会对这个解释感到满意.如果我们可以解压到一个包含 0 个元素的列表,我们也应该能够解压到一个包含 0 个元素的元组,不是吗?但是:

<预><代码>>>>() = ()文件<stdin>",第 1 行语法错误:不能分配给 ()

似乎解包规则不适用于元组,因为它们适用于列表.对于这种不一致,我想不出任何解释.这种行为有原因吗?

解决方案

@user2357112 关于这似乎是巧合的评论似乎是正确的.Python 源代码的相关部分位于 Python/ast.c:

switch (e->kind) {# 几个案例被剪掉案例列表_种类:e->v.List.ctx = ctx;s = e-> v.List.elts;休息;案例 Tuple_kind:如果(asdl_seq_LEN(e-> v.Tuple.elts)){e->v.Tuple.ctx = ctx;s = e-> v.Tuple.elts;}别的 {expr_name = "()";}休息;# 剪掉了几个案例}/* 检查开关设置的错误字符串 */如果(expr_name){字符缓冲区[300];PyOS_snprintf(buf, sizeof(buf),"不能 %s %s",ctx == 商店?分配给":删除",expr_name);返回 ast_error(c, n, buf);}

tuples 有一个明确的检查,长度不为零并在它是时引发错误.lists 没有任何此类检查,因此不会引发异常.

当分配给空元组是错误的时,我没有看到允许分配给空列表的任何特殊原因,但也许有一些我没有考虑的特殊情况.我建议这可能是一个(微不足道的)错误,并且两种类型的行为应该相同.

This came up in a recent PyCon talk.

The statement

[] = []

does nothing meaningful, but it does not throw an exception either. I have the feeling this must be due to unpacking rules. You can do tuple unpacking with lists too, e.g.,

[a, b] = [1, 2]

does what you would expect. As logical consequence, this also should work, when the number of elements to unpack is 0, which would explain why assigning to an empty list is valid. This theory is further supported by what happens when you try to assign a non-empty list to an empty list:

>>> [] = [1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack

I would be happy with this explanation, if the same would also be true for tuples. If we can unpack to a list with 0 elements, we should also be able to unpack to a tuple with 0 elements, no? However:

>>> () = ()
  File "<stdin>", line 1
SyntaxError: can't assign to ()

It seems like unpacking rules are not applied for tuples as they are for lists. I cannot think of any explanation for this inconsistency. Is there a reason for this behavior?

解决方案

The comment by @user2357112 that this seems to be coincidence appears to be correct. The relevant part of the Python source code is in Python/ast.c:

switch (e->kind) {
    # several cases snipped
    case List_kind:
        e->v.List.ctx = ctx;
        s = e->v.List.elts;
        break;
    case Tuple_kind:
        if (asdl_seq_LEN(e->v.Tuple.elts))  {
            e->v.Tuple.ctx = ctx;
            s = e->v.Tuple.elts;
        }
        else {
            expr_name = "()";
        }
        break;
    # several more cases snipped
}
/* Check for error string set by switch */
if (expr_name) {
    char buf[300];
    PyOS_snprintf(buf, sizeof(buf),
                  "can't %s %s",
                  ctx == Store ? "assign to" : "delete",
                  expr_name);
    return ast_error(c, n, buf);
}

tuples have an explicit check that the length is not zero and raise an error when it is. lists do not have any such check, so there's no exception raised.

I don't see any particular reason for allowing assignment to an empty list when it is an error to assign to an empty tuple, but perhaps there's some special case that I'm not considering. I'd suggest that this is probably a (trivial) bug and that the behaviors should be the same for both types.

这篇关于为什么分配给空列表有效而不分配给空元组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆