Python 的一个特别之处在于:如果没有使用 global 语法,其赋值操作总是在最里层的作用域。赋值不会复制数据,只是将命名绑定到对象。删除也是如此:del x 只是从局部作用域的命名空间中删除命名 x 。事实上,所有引入新命名的操作都作用于局部作用域。特别是 import 语句和函数定义将模块名或函数绑定于局部作用域(可以使用 global 语句将变量引入到全局作用域)。
global 语句用以指明某个特定的变量为全局作用域,并重新绑定它。nonlocal 语句用以指明某个特定的变量为封闭作用域,并重新绑定它。
9.2.1. 作用域和命名空间示例
以下是一个示例,演示了如何引用不同作用域和命名空间,以及 global 和 nonlocal 如何影响变量绑定:
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam
1
2
3
4
注意:local 赋值语句是无法改变 scope_test 的 spam 绑定。nonlocal 赋值语句改变了 scope_test 的 spam 绑定,并且 global 赋值语句从模块级改变了 spam 绑定。
你也可以看到在 global 赋值语句之前对 spam 是没有预先绑定的。
9.3. 初识类
类引入了一些新语法:三种新的对象类型和一些新的语义。
9.3.1. 类定义语法
类定义最简单的形式如下:
class ClassName:
<statement-1>
.
.
.
<statement-N>
1
2
3
4
5
6
类的定义就像函数定义( def 语句),要先执行才能生效。(你当然可以把它放进 if 语句的某一分支,或者一个函数的内部。)
# Function defined outside the class
def f1(self, x, y):
return min(x, x+y)
class C:
f = f1
def g(self):
return 'hello world'
h = g
1
2
3
4
5
6
7
8
9
现在 f, g 和 h 都是类 C 的属性,引用的都是函数对象,因此它们都是 C 实例的方法-- h 严格等于 g 。要注意的是这种习惯通常只会迷惑程序的读者。
for element in [1, 2, 3]:
print(element)
for element in (1, 2, 3):
print(element)
for key in {'one':1, 'two':2}:
print(key)
for char in "123":
print(char)
for line in open("myfile.txt"):
print(line, end='')
1
2
3
4
5
6
7
8
9
10
这种形式的访问清晰、简洁、方便。迭代器的用法在 Python 中普遍而且统一。在后台, for 语句在容器对象中调用 iter() 。该函数返回一个定义了 next() 方法的迭代器对象,它在容器中逐一访问元素。没有后续的元素时, next() 抛出一个 StopIteration 异常通知 for 语句循环结束。你可以是用内建的 next() 函数调用 next() 方法;以下是其工作原理的示例:
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
>>> for char in reverse('golf'):
... print(char)
...
f
l
o
g
1
2
3
4
5
6
7
8
9
10
11
前一节中描述了基于类的迭代器,它能作的每一件事生成器也能作到。因为自动创建了 iter() 和 next() 方法,生成器显得如此简洁。