Python 奇特的自引用
下面是一个创建自引用列表并演示自引用的 Python 示例:
奇特的结果
下面是一个创建自引用列表并演示自引用的 Python 示例:
>>> a = a[0] = [0] >>> a [[...]] >>> a[0] [[...]] >>> a[0][0] [[...]] >>> a is a[0] True
输出结果显示,a[0] 指向 a 本身,这使得它成为一个自引用列表。 为什么这段简单的代码会创建一个自引用列表? 因为在将列表 [0] 赋值给 a[0] 时,a 尚未定义,所以不应该出现 NameError 错误吗?
下面是另一个类似的示例,它也创建了一个自引用列表:
>>> a = a[0] = [0, 0] >>> a [[...], 0]
下面是一个类似的字典示例:
>>> a = a[0] = {} >>> a {0: {...}}
请注意,在上述示例中,0 被用作字典键。 下面是另一个使用字符串键的非常简单的示例:
>>> a = a['k'] = {} >>> a {'k': {...}}
语言参考
我的第一个猜测是,这句话
a = a[0] = [0]
就像
new = [0]
a = new
a[0] = new
这确实会产生一个自引用 list。
The Python Language Reference 第 7.2 节(赋值语句)证实了这种行为。 在此引用该节的相关部分:
赋值语句用于将名称(重新)与值绑定,并修改可变对象的属性或item:
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression) target_list ::= target ("," target)* [","] target ::= identifier | "(" [target_list] ")" | "[" [target_list] "]" | attributeref | subscription | slicing | "*" target
(有关 attributeref、订阅和切分的语法定义,请参见 Primaries)。
赋值语句会对表达式列表(记住,表达式列表可以是单个表达式,也可以是逗号分隔的列表,后者产生的是一个元组)进行评估,并将评估出的单个对象从左到右赋值给每个目标列表。
我们看到赋值语句的定义如下:
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)
因此
a = a[0] = [0]
有两个 target_list 元素(a 和 a[0])和一个 starred_expression 元素([0])。 因此,右侧的同一个列表从左到右被赋值给 a 和 a[0],即首先将列表 [0] 赋值给 a,然后将 a[0] 设置为同一个列表。 结果,a[0] 被设置为 a 本身。
语句的行为
a = a[0] = {}
可以用类似的方法来解释。首先将右侧的字典对象赋值给 a,然后在同一字典中插入键 0。最后,a[0] 的值被设置为同一个字典。换句话说,a[0] 被设置为 a 本身。
更多实验
首先对右侧的表达式列表进行执行,然后将执行结果从左到右赋值给每个目标列表,这解释了我们在前面章节中观察到的行为。这种从左到右的赋值在主流编程语言中并不常见。例如,在 C、C++、Java 和 JavaScript 中,简单赋值操作符 (=) 具有从右到左的关联性。Python 中的从左到右赋值可以通过一些故意的错误来进一步证明。下面是一个例子:
>>> a[0] = a = [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'a' is not defined
在本例中,当赋值到 a[0] to 时,名为 a 的变量尚未定义,因此导致 NameError。
下面是另一个例子:
>>> a = a[0] = 0 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'int' object does not support item assignment
在此示例中,首先将 0 赋值给 a。然后需要对 a[0] 进行求值,然后才能将 0 赋值给它,但求值失败,因为 a 是 int 类型,不支持订阅(也称为索引),所以会出现 TypeError。
你也许感兴趣的:
- 揭秘 Python 的 10 个隐藏技巧
- 如果您使用 Python… 你现在就需要了解这 3 个工具!
- 【外评】Python 为何如此糟糕…
- 【外评】用 Python 解释 Rust 背后的思想或理念
- Python 版本之间的主要变化摘要
- 【外评】Python 与苹果应用商店的拒绝作斗争
- 【外评】使用不安全的 Python 将速度提高 100 倍
- 谷歌裁掉整个 Python 团队!PyTorch 创始人急得直骂人:“WTF!核心语言团队无可替换”
- 谷歌Python团队全员被裁——负责内部Python所有基础设施、曾对数亿行代码执行自动重构
- 【译文】Python–一种深受喜爱但永远存在缺陷的语言
你对本文的反应是: