在 Python 2 中,如何写入父作用域中的变量?

新手上路,请多包涵

我有一些代码,例如:

 def example():
    # other logic omitted

    stored_blocks = {}
    def replace_blocks(m):
        block = m.group(0)
        block_hash = sha1(block)
        stored_blocks[block_hash] = block
        return '{{{%s}}}' % block_hash

    num_converted = 0
    def convert_variables(m):
        name = m.group(1)
        num_converted += 1
        return '<%%= %s %%>' % name

    fixed = MATCH_DECLARE_NEW.sub('', template)
    fixed = MATCH_PYTHON_BLOCK.sub(replace_blocks, fixed)
    fixed = MATCH_FORMAT.sub(convert_variables, fixed)

    # more logic...

将元素添加到 stored_blocks 工作正常,但我无法在第二个嵌套函数中增加 num_converted 。我得到一个异常,上面写着 UnboundLocalError: local variable 'num_converted' referenced before assignment

我知道在 3.x 中,我可以尝试 nonlocal num_converted ,但是如何解决 2.x 中的问题?我不想为此使用全局变量。

原文由 ThiefMaster 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 427
2 个回答

问题: 这是因为 Python 的作用域规则是疯狂的。 += 赋值运算符的存在将目标 num_converted 标记为封闭函数作用域的局部,并且在 Python 2.x 中没有合理的方法来访问仅一个作用域级别从那里出来。只有 global 关键字可以将变量引用提升到当前范围之外,它会直接将您带到顶部。

修复:num_converted 转换为单元素数组。

 num_converted = [0]
def convert_variables(m):
    name = m.group(1)
    num_converted[0] += 1
    return '<%%= %s %%>' % name

原文由 Marcelo Cantos 发布,翻译遵循 CC BY-SA 3.0 许可协议

(编辑后的答案见下文)

你可以使用类似的东西:

 def convert_variables(m):
    name = m.group(1)
    convert_variables.num_converted += 1
    return '<%%= %s %%>' % name

convert_variables.num_converted = 0

这样, num_converted 用作 convert_variable 方法的类似 C 的“静态”变量


(编辑)

 def convert_variables(m):
    name = m.group(1)
    convert_variables.num_converted = convert_variables.__dict__.get("num_converted", 0) + 1
    return '<%%= %s %%>' % name

这样,您就不需要在主程序中初始化计数器。

原文由 PabloG 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题