当前位置: 首页 > 面试题库 >

Python局部变量编译原理

解飞语
2023-03-14
问题内容
def fun():  
    if False:
        x=3
    print(locals())
    print(x)
fun()

输出和错误消息:

{}
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-57-d9deb3063ae1> in <module>()
      4     print(locals())
      5     print(x)
----> 6 fun()

<ipython-input-57-d9deb3063ae1> in fun()
      3         x=3
      4     print(locals())
----> 5     print(x)
      6 fun()

UnboundLocalError: local variable 'x' referenced before assignment

我想知道python解释器如何工作。请注意,x =
3根本不会运行,并且不应将其视为局部变量,这意味着错误将是“未定义名称’x’”。但是,查看代码和错误消息并非如此。任何人都可以在这种情况下解释python解释器的编译机制原理吗?


问题答案:

因此,Python始终会将每个函数中的每个名称归类为 localnon-localglobal之一
。这些名称范围是排他的;在每个函数中(嵌套函数中的名称都有其自己的命名范围),每个名称只能属于这些类别之一。

当Python编译此代码时:

def fun():
    if False:
        x=3

它将产生一个抽象的语法树,如下所示:

FunctionDef(
    name='fun', 
    args=arguments(...), b
    body=[
        If(test=NameConstant(value=False),
            body=[
                Assign(targets=[Name(id='x', ctx=Store())], value=Num(n=3))
            ], 
            orelse=[])
    ]
)

(为简洁起见,省略了一些内容)。现在,当将此抽象语法树编译为代码时,Python将扫描所有名称节点。如果存在Name带有的节点,则ctx=Store()该名称被认为是封闭的
本地 名称FunctionDef,除非在同一函数定义中用global(即global x)或nonlocalnonlocal x)语句覆盖该名称。

ctx=Store()主要在将名称用于赋值的左侧或在循环中用作迭代变量时,才会发生这种情况for

现在,当Python将其编译为字节码时,生成的字节码为

>>> dis.dis(fun)
  4           0 LOAD_GLOBAL              0 (print)
              3 LOAD_FAST                0 (x)
              6 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
              9 POP_TOP
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE

优化器if完全删除了该语句。但是,由于变量已被标记为函数的 局部 变量,因此LOAD_FAST用于x,这将导致只能x局部
变量和局部变量进行访问。由于x尚未设置,因此UnboundLocalError将引发。print另一方面,该名称从未分配给它,因此在该函数中被视为全局名称,因此其值将被加载LOAD_GLOBAL



 类似资料:
  • 本文向大家介绍Python局部变量与全局变量区别原理解析,包括了Python局部变量与全局变量区别原理解析的使用技巧和注意事项,需要的朋友参考一下 1、局部变量 输出: before change: Yang Li after change 你好 在外面看看name改了么? Yang Li 2、全局变量 输出: 3、nonlocal 全局与局部变量 在子程序中定义的变量称为局部变量,在程序的一开始

  • 问题内容: 我了解Python中局部变量和全局变量的概念,但是我只是有一个问题,为什么下面的代码中会出现错误?Python逐行执行代码,因此在读取第5行之前,它不知道a是局部变量。Python尝试执行第5行后,会回退一行并将其标记为错误吗? 问题答案: 设置和测试 为了分析您的问题,让我们创建两个独立的测试函数来复制您的问题: 版画。因此,调用此函数不是问题,而是在下一个函数上: 我们收到一个错误

  • 问题内容: 此代码为何起作用: 但这给出了“分配前引用的局部变量’var’”错误: 问题答案: 因为在第一个代码中,您已经创建了一个局部变量并使用了它的值,而在第二个代码中,您正在使用局部变量,而没有对其进行定义。 因此,如果要使第二个功能正常工作,则需要声明:- 在使用该功能之前。 而在此代码中: 更新 :- 但是,按照@Tim的注释,您不应在函数内部使用变量。最好在使用变量之前先定义变量,然后

  • 问题内容: 我正在使用handlebars.js,我想开始对所有内容进行预编译,但是似乎找不到找到预编译部分的方法。我的大部分模板实际上都是局部的。我尝试将它们像常规模板一样对待,但是将它们作为部分模板调用是行不通的。 有什么方法可以预编译局部函数,或者从另一个模板中调用一个模板吗? 问题答案: 我找到了一个更好的方法:将所有的部分代码预编译为模板,然后在代码中使用它们之前,添加以下行: 改进之处

  • 主要内容:Python局部变量,Python全局变量,获取指定作用域范围中的变量所谓 作用域(Scope),就是变量的有效范围,就是变量可以在哪个范围以内使用。有些变量可以在整段代码的任意位置使用,有些变量只能在函数内部使用,有些变量只能在 for 循环内部使用。 变量的作用域由变量的定义位置决定,在不同位置定义的变量,它的作用域是不一样的。本节我们只讲解两种变量, 局部变量和 全局变量。 Python局部变量 在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能

  • 问题内容: 我正在尝试使用exec运行一段python代码。 这导致以下输出 但是,如果我将代码更改为此- 然后工作正常-提供以下输出- 显然,A存在并且可以访问-在第一段代码中出了什么问题?我正在使用2.6.5,欢呼声, 科林 更新1 如果我检查类中的locals()- 然后很明显,locals()在两个地方都不相同- 但是,如果我这样做,就没有问题- 更新2 好的,所以这里的文档-http:

  • 主要内容:局部变量,全局变量,局部变量和全局变量的综合示例在《 C语言形参和实参的区别》中提到,形参变量要等到函数被调用时才分配内存,调用结束后立即释放内存。这说明形参变量的作用域非常有限,只能在函数内部使用,离开该函数就无效了。 所谓 作用域( Scope ) ,就是变量的有效范围。 不仅对于形参变量,C语言中所有的变量都有自己的作用域。决定变量作用域的是变量的定义位置。 局部变量 定义在函数内部的变量称为 局部变量(Local Variable) ,

  • Lua 的设计有一点很奇怪,在一个 block 中的变量,如果之前没有定义过,那么认为它是一个全局变量,而不是这个 block 的局部变量。这一点和别的语言不同。容易造成不小心覆盖了全局同名变量的错误。 定义 Lua 中的局部变量要用 local 关键字来显式定义,不使用 local 显式定义的变量就是全局变量: g_var = 1 -- global var local l_va