6.00 Introduction to Computer Science and Programming lec3 & lec4
之所以这两个一起写,是因为Lec3对我而言没什么内容,Python的东西不多。
Lec3的一个核心是:一个程序会在什么时候停止?我认为有三种情况:1. 返回正确的值。2. 返回错误的值。3. 报错
Python:
for variable in range(start, end):
statement
Lec4里function终于闪亮登场了。function由三部分组成:名字,参数和方法体,function的特点:Decomposition和Abstraction,我的理解是代码复用和封装。当然,人家讲的更有道理,Decomposition是指将一个系统分解为相互独立、可管理的子部分。Abstraciton则是创建了一个黑盒,输入获得输出。
当方法被调用时,将产生下面这些操作:
- 形参绑定到实参的值
- 在进入函数时,将生成一个新的Scope
Python中一个很有趣的概念是Scope。Scope是指name到object的映射,变量、函数都有自己的Scope。Scope也叫stack frames。我认为stack frame来自于编译器的实现,程序在运行时实际就是在不断的进行压栈、弹栈,这方面的内容可以参考《C专家编程》。下面关于Scope的介绍,参考自:http://www-inst.eecs.berkeley.edu/~selfpace/cs9honline/Q2/scope.html
有关Python中的Scope,要记住三点:
1. Scope中所有的name都same
学习Python时首先要记住的是Python中的一切都是有名字的,比如数字,字符串,函数,类型,变量等。Python中所有的name都same,这与Java或C++不同,不同类型的name可以一样,例如类blerg可以和变量blerg同时存在。执行下面的代码,可以更好地理解这一点。
spoon = 2 + 2 print spoon def spoon(x): return x + 3 print spoon spoon = 'foo' print spoon在上面的Python代码中,只有一个name spoon。spoon首先是一个数字,然后变成一个函数,最后成为字符串的name。
2. name的Scope是它所在的文件,类或函数
每个name都属于一个namespace(在scheme中叫“environment”)。
def genius(): x = 2 + 2 print 'two plus two is', x在上面的例子中,x的Scope为函数genius。当程序进入函数时,会首先将genius压入栈中,然后x的作用域就是那个栈帧(StackFrame)。
x = 2 + 2 def genius(): print 'two plus two is', x def dummy(): x = 3 print 'two plus two is', x def gullible(x): print 'two plus two is', x genius() dummy() print x genius() gullible(5)将上面的程序存到一个文件中,如scopedemo.py,执行之,会出现有趣的结果。
上面的代码首先为x创建了一个File范围的Scope,genius函数创建了一个scope,但genius的scope中并不存在一个x。当在genius中引用x的时候,Python首先在genius的scope中查找,若没找到,则去包含此Scope的外层Scope查找,因此genius中输出x的值为4,如下图所示:
在genius中引用的是外部Scope定义的x。
在dumm()中,有自己的x定义,因此这里x引用的是内部Scope的x。
在gullible(x)中,形参x在gullible()函数内声明了一个
3. name属于它所在的namespace
在一个namespace中,name的作用域是整个namespace,而不是从其声明的位置开始。例如在dummy中,即使x = 3出现在dummy()的最后一行,x的scope仍然是dummy函数。如下面的例子:
x = 1 def kumquat(): x = 5 print x def gazebo(): print x # many lines of code... # many lines of code... # many lines of code... x = 5 def hullabaloo(y): if y > 3: x = 5 print x kumquat() gazebo() hullabaloo(1) hullabaloo(6)在调用gazebo()的时候,尽管对x的赋值语句在最后,但其Scope却是整个函数,因此gazebo()的print x语句会报错,而不是输出1.
如何将一个变量的值传递到外层的scope呢?可以使用global关键字实现,global关键字将使变量的Scope扩展为File级。
x = 2 def foible(): x = x + 1 def spatula(): global x x = x + 1 print x foible() print x spatula() print x在上面的代码中,spatula()执行之后x的值变为3,因为spatula()中x的Scope是File。