作用域与命名空间这两个概念,一听起来,觉得“命名空间”是大的范围概念,“作用域”是小的范围概念(例如:Java编程语言中),但在Python中情况没那么简单。
一个模块(一py文件)是全局命名空间,在全局命名空间中的属性(变量、类、函数)是全局属性;模块中的一个类、一个对象、一个函数是局部命名空间,在局部命名空间中的属性(变量、类、函数、方法)是局部属性。全局属性的作用域是整个文件的代码范围,实际上就包括了全局命名空间和模块中的全部局部空间;局部属性的作用域就包括它被命名的那个命名空间及镶套在这个局部命名空间中的局部命名空间。Python中的命名空间可以镶套,但不能包含。因此,属性的作用域包括它被命名的命名空间和镶套在这个命名空间中的局部命名空间。由此看来,作用域至少包括一个命名空间,作用域的范围大,命名空间的范围小。
上节课已经讨论作用域内属性或变量的引用,这一节将讨论引用作用域外的属性。
“借人物,要明求”——在属性名称之前加上命名空间的标识符(模块名称、类名称或对象变量),用点号(.)连接。
函数命名空间中变量测试,程序和结果:
,
可见,函数中定义的变量不构成函数的属性,所以无法用增加命名空间的前缀进行引用。
函数命名空间中函数测试,程序和结果:
,
可见,函数中定义的函数也不构成函数的属性,所以无法用增加命名空间的前缀进行引用。
函数命名空间中类测试,程序和结果:
,
可见,函数中定义的类也不构成函数的属性,所以无法用增加命名空间的前缀进行引用。
函数中定义的变量、函数和类都不构成函数的属性,在函数之外是不可见的(不可引用的)。
类命名空间中变量、方法和类测试,程序和结果:
,
可见,类中定义的变量、方法和类都构成类的属性,所以可以用增加命名空间前缀进行引用。
类中方法命名空间中变量、方法和类测试(类内/类外),程序和结果:
;
。
可见,类中的方法与函数一样,其中的变量、方法和类都不构成类中的方法的属性,在方法外是不可见的。
类中类命名空间中变量、方法和类测试,程序和结果(类内):
;
程序和结果(类外):
。
可见,类中类的命名空间与类的命名空间一样,变量、方法和类都构成属性,可以用属性引用方法引用。另外,类内和类外的引用方式有差别,类内不需要Test.前缀。引用前缀可以根据镶套关系到引用者和被引用者的共同命名空间(不包括)为止。
练习题:把这课的测试输入电脑自行测试一次。