变量的作用是有范围的,准确说世上任何事物对外作用都是有范围限制的。而变量或者符号,背后代表着不同的意思,能对他们求值,就要去在求值的地方能看见它们,这些地方就是变量的作用域。
作用域粗略的可以分为局部作用域和全局作用域。
局部变量就具有局部作用域,分为函数内变量、类变量和文件访问变量。作用域不同,变量的初始化时间也不相同、默认的初始值也会不同,这跟不同语言的实现相关。
函数作用域:
每次函数调用时,运行系统都会为函数建立局部环境,这个环境里就保存了一些局部变量的值,以便执行函数内语句时,对局部变量进行取值。这其中,包括函数的形参,当发生函数调用时,首先会将实参赋给形参,并函数内定义的变量也保存在这个局部环境里,每次调用都重新赋值。
>>> total = 0
>>> def sum_f(x, y):
total = x + y
print "Inside the function, value of total is: ", total
>>> sum_f(3, 4)
Inside the function, value of total is: 7
>>> print "Outside the function, value of total is: ", total
Outside the function, value of total is: 0
>>>
以上述为例,x、y和total都是局部变量,在变量结束后,保存这些值的局部环境会被销毁。但是x、y与total有点不同,因为在全局变量里有个同名的变量也叫total,这个全局变量保存在全局环境里。在函数内,局部变量会屏蔽全局变量,如果有同名的话。从上述代码可以看出,全局的total值并没有被改变。
>>> total = 0
>>> def sum_f(x, y):
global total
total = x + y
print "Inside the function, value of total is: ", total
>>> sum_f(3, 4)
Inside the function, value of total is: 7
>>> total
7
>>> x
Traceback (most recent call last):
File "<pyshell#12>", line 1, in <module>
x
NameError: name 'x' is not defined
#x变量未定义,注意变量total在函数内与上面所列代码的不同之处
global修饰的变量total表明,函数sum_f里的total是全局变量,因此在函数调用结束后,输出的total值跟函数内是相同的。同时,在函数调用结束后,试图访问x变量,这是运行系统给出错误提示,"name 'x' is not defined",这句话验证了上面提到的,函数调用发生时,会建立局部环境以保存形参的值,在函数调用结束时,这个局部环境被销毁。
类变量:
与函数变量不同。类变量和类方法绑定,作为自定义的一种类型,叫做“封装”。也就是类变量在类内部都是可见的,不管类方法是public还是private。
全局变量:
全局变量就是在全局方位内,该变量都是可见的,无论是在函数内,还是在类内部。但是如果这三者之间发生变量相同时,访问的优先级是不同的,高低顺序与它们的作用范围大小相反,也就是函数变量高于类变量、高于全局变量。
变量与标示符:
variable和identifier的区别不是那么容易划分的,就像代码与数据的界限也不是那么清晰的。标示符背后可以代表数、符号和“计算过程”——函数。自定义的全局方程foo与某语言提供的全局操作符加号(+),本质上是一样的,都代表着某种计算模式。但是为了便于符号间的隔离,符号名重名,尤其是在大规模多人开发的程序中,将标示符进行按某种功能相近放在一起,作为一个访问单元,有效缓解重名问题。这就是C语言的include,C++的namespace,和Python的import的目的。当然也是为了编译的方便。