2.4.2 名称空间
本节目标:
了解LEGB名称空间。
能指出之前写过的程序中的变量都属于哪个名称空间。
了解闭包。
当我们使用turtle库中的类时,我们用turtle.Turtle。为什么要把库名加上? 原因很容易想到,因为别的库中也可能有Turtle。
y = 3
def func():
y = 1
print("函数func:", y) # 输出:1
func()
print("函数外:", y) # 输出:3运行以上代码我们发现,在函数里面对y的值进行改变似乎没有影响到函数外y的值。
Learning By Reading 难度:★★ 重要性:★★★★★
阅读材料,了解Python的命名空间。
材料中有一个链接很好地解释了“闭包”的概念。
里面提到的“装饰器”将在下一节介绍,可以先跳过与“装饰器”有关的部分。
另一个例子,
def polygon_factory(n):
# 返回一个正n边形函数polygon
def polygon(turtle, side):
return turtle.polygon(n, side) # 绑定了闭包polygon_factory中的名称n和局部名称空间中的turtle和side
# 翻译成人话即这里的n用的是polygon_factory的参数n,而turtle和side是局部变量
return polygon
pentagon = polygon_factory(5) # 五边形函数
octagon = polygon_factory(8) # 八边形函数
my_turtle = MyTurtle()
pentagon(my_turtle, 50) # 边长为50的五边形
octagon(my_turtle, 50) # 边长为50的八边形每个名称都有自己的“作用域”(scope),即这个名称可以在哪个范围内被绑定。 比如上面的turtle和side,其作用域是polygon这个函数。 出了这个函数,Python就不认turtle和side这个名字了。 而polygon和n,其作用域是polygon_factory这个函数,也包括在polygon_factory里面定义的polygon函数。
而靠里面的名称会覆盖掉靠外面的名称,本节第一段代码就是例子。
另外一点需要注意的是,函数体中的名称,其作用域可以扩展到函数中定义的函数里。 就像上面的n可以在polygon中使用。
但类体中的名称不会扩展到类方法和列表解析中。
即x的作用域延伸到了some_method里,但y的作用域不能。
另一个区别是
在函数中,只要用到了变量x,那么,函数体中的所有x都会被绑定到局部名称空间的x, 所以y = x的时候会报错说“变量x在赋值前引用”。
而类体中,遇到这种情况时,Python会自己去全局名称空间里面找x。
Last updated