栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么“ ord”在这里被视为未分配变量?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么“ ord”在这里被视为未分配变量?

这与编译器在编译为字节码时基于不相关分支进行静态分析无关;这要简单得多。

Python有一个区分全局变量,闭包变量和局部变量的规则。在函数中分配的所有变量(包括隐式分配给参数的参数)都是局部变量(除非它们具有

global
or
nonlocal
语句)。参考文档的“绑定和命名”及后续章节对此进行了说明。

这并不是要使解释器简单,而是要使规则足够简单以使人类读者通常可以直观地理解,并且在不直观时可以很容易地被人解决。(这对于此类情况尤其重要-
行为并非到处都是直观的,因此Python将规则保持足够简单,以使一旦学习,该情况仍然很明显。但是您肯定必须在此之前学习该规则是的,当然,大多数人是第一次对规则感到惊讶来学习该规则的…)

即使优化器足够聪明,可以完全删除与之相关的任何字节码

if False: ord=None
ord
但根据语言语义规则,仍必须是局部变量。

因此:

ord=
函数中有一个,因此对的所有引用
ord
都是对局部变量的引用,而不是碰巧具有相同名称的任何全局或非局部变量,因此您的代码是
UnboundLocalError


许多人在不了解实际规则的情况下走了过来,而是使用了更简单的规则:变量是

  • 如果可能,则为本地,否则为
  • 如果可能,将其封闭,否则
  • 如果是全局变量,则为全局变量,否则
  • 内置(如果内置),否则
  • 一个错误

尽管这种方法在大多数情况下都有效,但在某些情况下(例如这种情况)可能会产生误导。具有以Lisp样式完成LEGB范围界定的语言会看到它

ord
不在本地名称空间中,因此会返回全局名称,但Python不会这样做。您可以说这
ord


在本地名称空间中,但是绑定到一个特殊的“未定义”值,它实际上接近幕后发生的事情,但这不是Python规则所说的,尽管这样做可能更直观简单的情况下,很难进行推理。


如果您好奇这是如何工作的,请执行以下操作:

在CPython中,编译器将扫描您的函数以查找所有以标识符为目标的赋值,并将其存储在数组中。它删除全局变量和非局部变量。该数组最终将作为您的代码对象的数组

co_varnames
,因此,假设您
ord
co_varnames[1]
。然后,对该变量的每次使用都会编译为
LOAD_FAST1
STORE_FAST 1
,而不是编译为
LOAD_NAME
STORE_GLOBAL
或其他操作。解释时,这
LOAD_FAST1
只是将框架的内容加载
f_locals[1]
到堆栈中。它
f_locals
以NULL指针数组而不是指向Python对象的指针开始,如果
LOAD_FAST
加载了NULL指针,它将引发
UnboundLocalError



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/639904.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号