【问题标题】:python symbol can be global and local in the same scopepython符号可以在同一范围内是全局的和局部的
【发布时间】:2020-07-17 07:07:17
【问题描述】:

考虑这个函数:

def content(path):
  global file # not useful but valid
  with open(path) as file:
    return file.read()

在生成符号表(使用模块symtable)并在函数content 的范围内检查符号file 时,它同时是全局和局部的。调用此函数后,全局名称file 将绑定到文件对象。所以我想知道为什么函数范围内的符号file也被认为是本地符号?

这里是重现行为的代码(将其放在一个文件中,例如名为global_and_local.py):

import symtable

def content(path):
  global file
  with open(path) as file:
    return file.read()

symtable_root = symtable.symtable(content(__file__), __file__, "exec")
symtable_function = symtable_root.get_children()[0]
symbol_file = symtable_function.lookup('file')
print("symbol 'file' in function scope: is_global() =", symbol_file.is_global())
print("symbol 'file' in function scope: is_local() =", symbol_file.is_local())
print("global scope: file =", file)

生成以下输出:

symbol 'file' in function scope: is_global() = True
symbol 'file' in function scope: is_local() = True
global scope: file = <_io.TextIOWrapper name='global_and_local.py' ...>

【问题讨论】:

    标签: python global-variables symbols


    【解决方案1】:

    由于某种原因,symtable defines is_local 用于检查符号的任何绑定操作是否发生在作用域(或注释,在此阶段与带注释的赋值混为一谈):

    def is_local(self):
        return bool(self.__flags & DEF_BOUND)
    

    而不是检查符号是否实际上是本地的,看起来像

    def is_local(self):
        return bool(self.__scope in (LOCAL, CELL))
    

    我不知道为什么。这可能是一个错误。我不认为像这样的模块有太多用处 - it took over a year 在任何人 noticed 之前添加 // 运算符破坏了旧的 parser 模块,所以我很容易看到这一点被忽视。

    【讨论】:

    • @coproc:赋值、函数定义、导入、用作for 循环目标等。任何可以重新绑定名称的东西。
    • 我已经提交了一份错误报告(参见bugs.python.org/issue40196)并参考了您的回答
    • symtable.Symbol.is_local() 现已修复:github.com/python/cpython/pull/19391
    • 啊,哎呀。 Python/symtable.c 处理 CELL 与其他范围有点不同,所以我没有意识到它是 LOCAL 的单独选项。不过,我很确定bool 是多余的(尽管在执行&amp; 的其他一些方法中它不是多余的)。
    • 我很高兴有人发现了这一点,所以我们不只是从一个错误转到另一个错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 2017-03-05
    • 2019-01-25
    • 1970-01-01
    相关资源
    最近更新 更多