本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这是本文档旧的修订版!
week 1 notes
<Control>-P
(previous) <Control>-N
(next)<Control>-D
exits a session
# import lib from specific url
from urllib.request import urlopen
编程语言通常会提供三种方式来生成复杂的指令:
表达式包括两种:
call exressions 是复合表达式的一种,是 $f(x)$ 的一般形式,指计算(mapping)的过程。其特点:
name 是一种用于关联 computational objects 的方式。name 可以通过与该对象绑定(binding)的方式来与其关联,从而达到通过 name 来操作该对象的目的。name 的绑定方式有 3 种:
由于这种绑定关系的的存在,计算机需要分配一部分空间存储这些 name, object 以及关系。被分配的空间被称为环境(environment)。下面是 python 的示例:
#binding example
#import name with bound function
>>>from math import sqrt
>>>sqrt(256)
#assign name to a value
>>> radius = 10
#assgin name to an function
>>> max
#<built-in function max>
>>>f = max
#define a function
def square(x):
return x*x
>>> area, circumference = pi * radius * radius, 2 * pi * radius
>>> area
314.1592653589793
>>> radius = 11
>>> area
314.1592653589793
#another assignment needed for updating the value of area
>>> area = pi * radius * radius
380.132711084365
x
,y
先被取值,再进行了重新绑定:
>>> x, y = 3, 4.5
>>> y, x = x, y
>>> x
4.5
>>> y
3
基础的解释顺序为:
特点是:要计算主表达式,就得先计算出其子表达式的值。这种评估的过程被称为递归(recursive)
如果 operand 是子表达式(sub-expression),那么对该表达式按基础顺序继续执行,直到得到值(value)。例子如下:
该结构被称为表达式树(expression tree)
注意 CS 中树的构建是从上往下的,也就意味着求出根表达式需要求出其节点的值。而相比一半的算数式子,表达式的结构非常有利于解释执行(解释)的顺序,尤其是在多层嵌套的前提下。
# the operation does not return any values, but changes value of x
x = 3
纯函数(pure function)指有输入(argument)并会产生输出 (the result) 的函数,比如:
>>> abs(-2)
2
非纯函数(Non-pure functions)指应用时带有“副作用(side effects)” 的函数(通常指改变解释器状态)。打印是一种常见的副作用:
>>> print(1, 2, 3)
1 2 3
实际上,print()
函数的打印值并不是其返回值。其返回值是 NoneType
类型的,值为 None
的变量:
>>> print(print(1), print(2))
1
2
None None
自定义函数是抽象过程中更加高级的做法。这种做法允许我们将 name 绑定到指定的复合指令集合上。比如这段程序:
>>> def square(x):
return mul(x, x)
实际上使用了 square
来抽象了让 x
自己乘以自己的过程。此处的 x
被称为 formal parameter,x
为自乘的数据提供了 name。
def <name>(<formal parameters>):
return <return expression>
environments 通过一系列的 frame 来衡量表达式。以 frame 为单位,每个 frame 内部都会存储对应的 name,以及该 name 绑定的 value.
在 python 中,默认存在一个全局(golbal)frame。赋值 / 外部导入的 name 都会存储在这个 frame 中:
function 的 binding (无论是导入的,还是自定义的),也存储在这里:
我们将存储在 frame 中的 name 称为 bound name,而出现在函数内部的,同样的 name 称为 intrinsic name。每个函数可以同时存在多个 bound name,但 intrinsic name 有且只有一个。
考虑以下函数:
from operator import add, mul
def square(x):
return mul(x, x)
def sum_squares(x, y):
return add(square(x), square(y))
result = sum_squares(5, 12)
sum_squares
. 此时 sum_squares
与自定函数绑定,其关系存储在 global frame 中。sum_square()
,也就是 result = sum_squares(5, 12)
这一步时,此时:sum_suqare()
专属的 local framesum_suqare()
内部 operand 的绑定关系。此处是 square()
。需要注意的是这里的 operator add()
是 built-in(外部导入的),因此其绑定存储在 global frame 中,而不是 sun_square()
的 local frame 中square()
,因此针对该函数的绑定,需要再创建一个 Local frame 进行存储x
,即便 name 相同,根据其所在的 local frame, 其绑定的 value 也不同。