Our subset of Python is now complex enough that the meaning of programs is non-obvious. What if a formal parameter has the same name as a built-in function? Can two functions share names without confusion? To resolve such questions, we must describe environments in more detail.
我们的Python子集现在已经足够复杂,程序的意义已经不明显了。如果形参和内置函数同名怎么办?两个函数可以共享名字而不混淆吗?要解决这些问题,我们必须更详细地描述环境。
An environment in which an expression is evaluated consists of a sequence of frames, depicted as boxes. Each frame contains bindings, each of which associates a name with its corresponding value. There is a single global frame. Assignment and import statements add entries to the first frame of the current environment. So far, our environment consists only of the global frame.
计算表达式的环境由一系列帧组成,用方框表示。每个帧包含绑定,每个绑定将一个名称与其对应的值相关联。有一个单一的全局帧。赋值和导入语句将条目添加到当前环境的第一个帧中。到目前为止,我们的环境只包括全局帧。
点击查看【codepen】
This environment diagram shows the bindings of the current environment, along with the values to which names are bound. The environment diagrams in this text are interactive: you can step through the lines of the small program on the left to see the state of the environment evolve on the right. You can also click on the “Edit code in Online Python Tutor” link to load the example into the Online Python Tutor, a tool created by Philip Guo for generating these environment diagrams. You are encouraged to create examples yourself and study the resulting environment diagrams.
这个环境图显示了当前环境的绑定,以及名称绑定到的值。本文中的环境图是交互式的:你可以通过左边的小程序来查看右边的环境演变状态。您还可以点击“在线Python Tutor中编辑代码”链接,将示例加载到在线Python Tutor中,这是Philip Guo创建的一个工具,用于生成这些环境图。我们鼓励您自己创建示例,并研究生成的环境图。
Functions appear in environment diagrams as well. An import statement binds a name to a built-in function. A def statement binds a name to a user-defined function created by the definition. The resulting environment after importing mul and defining square appears below:
函数也出现在环境图中。import语句将名称绑定到内置函数。def语句将名称绑定到由定义创建的用户定义函数。导入mul并定义square后的结果环境如下所示:
点击查看【codepen】
Each function is a line that starts with func, followed by the function name and formal parameters. Built-in functions such as mul do not have formal parameter names, and so … is always used instead.
每个函数都是以func开头的一行,后面是函数名和形式参数。像mul这样的内置函数没有正式的参数名称,所以总是用…来代替
The name of a function is repeated twice, once in the frame and again as part of the function itself. The name appearing in the function is called the intrinsic name. The name in a frame is a bound name. There is a difference between the two: different names may refer to the same function, but that function itself has only one intrinsic name.
一个函数的名字重复了两次,一次是在帧中,另一次是作为函数本身的一部分。出现在函数中的名称称为内在名称。帧中的名称是绑定名称。两者是有区别的:不同的名字可能指的是同一个函数,但是函数本身只有一个内在名字。
The name bound to a function in a frame is the one used during evaluation. The intrinsic name of a function does not play a role in evaluation. Step through the example below using the Forward button to see that once the name max is bound to the value 3, it can no longer be used as a function.
绑定到帧中的函数名称是在求值期间使用的名称。函数的内在名称在计算中不起作用。使用Forward按钮浏览下面的示例,可以看到一旦名称max绑定到值3,它就不能再用作函数。
点击查看【codepen】
The error message TypeError: ‘int’ object is not callable is reporting that the name max (currently bound to the number 3) is an integer and not a function. Therefore, it cannot be used as the operator in a call expression.
错误信息TypeError:’int’object is not callable,名称max(目前与数字3绑定)是一个整数而不是一个函数。因此,它不能被用作调用表达式中的运算符。
Function Signatures. Functions differ in the number of arguments that they are allowed to take. To track these requirements, we draw each function in a way that shows the function name and its formal parameters. The user-defined function square takes only x; providing more or fewer arguments will result in an error. A description of the formal parameters of a function is called the function’s signature.
函数签名。函数在允许接受的参数数量上有所不同。为了跟踪这些需求,我们以显示函数名及其形式参数的方式来绘制每个函数。自定义函数square只取x;提供更多或更少的参数将导致错误。对函数的形参的描述称为函数的签名。
The function max can take an arbitrary number of arguments. It is rendered as max(…). Regardless of the number of arguments taken, all built-in functions will be rendered as
函数max可以接受任意数量的参数。它被渲染为max(…).不管采用多少个参数,所有内置函数都将呈现为< name >(…),因为这些原函数从来没有明确定义过。