【问题标题】:How does Python interpreter actually interpret a program?Python解释器实际上是如何解释程序的?
【发布时间】:2021-12-29 03:06:57
【问题描述】:

拿一个示例程序:

c = 10

def myfunc():
    print(c)

myfunc()

这会按预期打印 10,但如果我们查看另一个程序:


c = 10

def myfunc():
    print(c)
    c = 1


myfunc()

上面写着:local variable 'c' referenced before assignment

在这里,如果 python 解释器实际上是逐行运行,它不应该在到达下一行之前打印10 以得出局部变量的结论吗?

Python 有一个词法分析器、分词器和解析器。它是否遍历所有代码,在逐行执行之前对其进行解析?

这就是为什么它可以说函数下面有一个局部变量吗?

【问题讨论】:

  • 在执行开始之前,所有的 Python 都会被编译为字节码 - 任何语法错误都会阻止你的代码运行,并且在这个编译步骤中也必须确定范围(因为字节码需要引用正确的变量位置)。
  • “解释器”并不意味着“逐行”。没有什么说解释器必须先执行一行才能读取下一行。
  • (即使它确实暗示了这一点,Python 也必须在到达调用函数的行之前读取整个函数定义。)
  • “[C]Python 有一个词法分析器、分词器和解析器。它是否会遍历所有代码,在执行 [字节码] 之前对其进行解析”——是的,确实如此。
  • 这能回答你的问题吗? Python Compilation/Interpretation Process

标签: python interpreter python-internals


【解决方案1】:

简介

在解释器接管之前,Python 会执行三个其他步骤:词法分析、解析和编译。这些步骤一起将源代码从文本行转换为包含解释器可以理解的指令的字节码。解释器的工作是获取这些代码对象并按照说明进行操作。

为什么?

所以 Python 在将源代码转换为字节码时会产生错误。在此步骤中,范围也被确定。这是因为字节码需要引用正确的变量位置。但是,在这种情况下,它现在被连线以引用未在作用域中定义的变量,从而导致运行时出错。

示例

在这段代码的 sn-p 中没有语法错误,也没有范围错误。

c = 10

def myfunc():
    print(c)

myfunc()

在这个程序中,c = 1 隐式地使变量成为局部变量。但是,这是在print(c) 之后定义的,而print(c) 尚未在其范围内定义。

c = 10

def myfunc():
    print(c)
    c = 1

myfunc()

如果你这样做了:

c = 10

def myfunc():
    c = 1
    print(c)


myfunc()

c = 10

def myfunc():
    global c # Changes the scope of the variable to make it accessible to the function
    print(c)
    c = 1


myfunc()

代码可以正常工作。

结论

回答你的问题:

它是否遍历所有代码,在执行它们之前对其进行解析 按行?

是的,确实如此。

【讨论】:

    【解决方案2】:

    问题不在于解释的顺序,如你所料的从上到下;这是范围。在 Python 中,当在较窄的函数范围内引用全局变量时,如果修改值,必须首先告诉代码全局变量是您要引用的变量,而不是新的局部变量.您可以使用 global 关键字来执行此操作。在这个例子中,你的程序实际上应该是这样的:

    c = 10
    
    def myfunc():
        global c
        print(c)
        c = 1
    
    
    myfunc()
    

    【讨论】:

    • 谢谢你的回复,恐怕不是我的问题。我知道 global 关键字以及为什么使用它。这只是一个例子。我的问题是 python 如何解释给定文件
    【解决方案3】:

    Miles C. 是正确的。 我猜你的代码是从结构化语言(如 C 或 C++)过来的。 Python 不会像 C 或 C++ 那样引用变量,它需要被告知这样做。 global 关键字告诉 python 你在函数之外寻找变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-23
      • 2019-12-03
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多