To evaluate a call expression whose operator names a user-defined function, the Python interpreter follows a computational process. As with any call expression, the interpreter evaluates the operator and operand expressions, and then applies the named function to the resulting arguments.

    为了求一个其操作符名为用户自定义函数的调用表达式,Python解释器遵循一个计算过程。与任何调用表达式一样,解释器求运算符和操作表达式,然后将命名函数应用于结果参数

    Applying a user-defined function introduces a second local frame, which is only accessible to that function. To apply a user-defined function to some arguments:

    应用一个用户定义的函数会引入第二个局部帧,这个帧只对该函数开放。要将一个用户定义的函数应用于一些参数。

    1. Bind the arguments to the names of the function’s formal parameters in a new local frame.
    2. Execute the body of the function in the environment that starts with this frame.

      1.在一个新的局部帧中,将参数与函数的形式参数名称绑定。

      1. 在以此帧开始的环境中执行函数体。

    The environment in which the body is evaluated consists of two frames: first the local frame that contains formal parameter bindings, then the global frame that contains everything else. Each instance of a function application has its own independent local frame.

    评估主体的环境由两个帧组成:首先是包含形式参数绑定的局部帧,然后是包含其他一切的全局帧。函数应用程序的每个实例都有自己独立的局部帧。

    To illustrate an example in detail, several steps of the environment diagram for the same example are depicted below. After executing the first import statement, only the name mul is bound in the global frame.

    为了详细说明一个示例,下面描述了同一个示例的环境图的几个步骤。在执行第一个import语句后,只有名字mul被绑定在全局帧中。

    image.png
    First, the definition statement for the function square is executed. Notice that the entire def statement is processed in a single step. The body of a function is not executed until the function is called (not when it is defined).

    首先,执行函数square的定义语句。注意,整个def语句是在一个步骤中处理的。直到函数被调用时(而不是定义时),函数体才会被执行。

    image.png
    点击查看【codepen】
    Next, The square function is called with the argument -2, and so a new frame is created with the formal parameter x bound to the value -2.

    接下来,square 函数被调用,参数为-2,因此创建了一个新的帧,将形参x绑定到值-2上。

    Then, the name x is looked up in the current environment, which consists of the two frames shown. In both occurrences, x evaluates to -2, and so the square function returns 4.

    然后,在当前环境中查找名称x,当前环境由所示的两个帧组成。在这两种情况下,x的值都是-2,因此square函数返回4

    image.png
    The “Return value” in the square() frame is not a name binding; instead it indicates the value returned by the function call that created the frame.

    Square ()帧中的“ return value”不是名称绑定,而是指创建帧的函数调用返回的值。

    Even in this simple example, two different environments are used. The top-level expression square(-2) is evaluated in the global environment, while the return expression mul(x, x) is evaluated in the environment created for by calling square. Both x and mul are bound in this environment, but in different frames.

    即使在这个简单的例子中,使用了两种不同的环境。顶层表达式 square (- 2)在全局环境中求值,而返回表达式 mul (x,x)在通过调用 square 创建的环境中求值。X mul 在这个环境中都是绑定的,但是在不同的环境中。

    The order of frames in an environment affects the value returned by looking up a name in an expression. We stated previously that a name is evaluated to the value associated with that name in the current environment. We can now be more precise:

    环境中帧的顺序会影响在表达式中查找名称时返回的值。在当前环境中,我们之前说过一个名称是根据与该名称相关联的值。我们现在可以更精确地说:

    Name Evaluation. A name evaluates to the value bound to that name in the earliest frame of the current environment in which that name is found.

    名称评估。一个名称评估为该名称所在的当前环境的最早帧中绑定到该名称的值。

    Our conceptual framework of environments, names, and functions constitutes a model of evaluation; while some mechanical details are still unspecified (e.g., how a binding is implemented), our model does precisely and correctly describe how the interpreter evaluates call expressions. In Chapter 3 we will see how this model can serve as a blueprint for implementing a working interpreter for a programming language.

    我们的环境、名称和函数的概念帧构成了一个评估模型;虽然一些机械细节仍未被指定(例如,如何实现绑定),但我们的模型确实准确无误地描述了解释器如何评估调用表达。在第三章中,我们将看到这个模型如何作为实现编程语言的工作解释器的蓝图。