python变量作用域,局部变量和全局变量
什么是变量作用域,该定义指的是变量的有效作用范围,比如在一个函数内的变量通常只能在该函数当中有效。
我们为什么要考虑python变量的作用域,或者说,python为什么要为变量设计作用域?就像c/c++中的命名空间一样。
简化编程
个人认为,计算机编程的语言设计变量作用域就是为了简化编程,比如下面这x,y两个函数:
def x(a,b):
pass
def y(a,b):
pass
我们为x,y这两个函数设计了相同的位置参数名,但它们之间是不会发生冲突的,想想,如果因为函数内的参数名或变量名发生了冲突而不得不用不同的名称,那得多麻烦,而且还要考虑词汇量的问题。
python变量作用域,局部变量和全局变量
一直在纠结我们的教程该如何把python的变量作用域讲得简单,理解起来可以更高效,而不至于一个概念接一个概念的那么烦琐。思来想去,个人认为,关于python变量的作用域可以从局部变量和全局变量这两个概念入手,或者说理解这两个就差不多了。
局部变量
局部变量的定义和特性:
- 只在特定范围内有效的变量;
- 通常出现在函数内部,而且在函数外部无效;
- 强烈建议,不管是python编程还是其他的语言编程,尽量只使用局部变量;
注意:大多数的编程实战开发,不管是python还是c/c++或其他的编程语言,通常都是采用函数式编程,简而言之就是计算机程序之间是用函数调用函数来完成的,所尽量使用局部变量,全局变量有什么坏处呢,在下面的示例的后面我们将会详细介绍。
局部变量示例
In[1]:
def x():
var_a = 1 #在函数内声明一个变量var_a,为局部变量
return var_a
print(var_a) #在函数外使用变量var_a
NameError Traceback (most recent call last)
<ipython-input-xxx> in <module>
2 var_a = 1
3 return var_a
----> 4 print(var_a)
NameError: name 'var_a' is not defined
从上面的例子我们可以发现,函数内部声明的变量的作用域仅限在函数内部,可以称为局部变量,在函数外部使用的话,就超出其使用范围——作用域,继而发生not defined错误,就是变量没有声明的错误。
全局变量
写在最前面,python编程过程中,尽量少用或不用全局变量。其定义和特性如下:
- 通常将声明在函数外部的变量称为全局变量;
- 在函数外部可用,在函数内部、类的内部等也可以使用,这是全局变量的优点也是其重大缺点;
- 重复一边,强烈建议,不管是python编程还是其他的语言编程,尽量不使用全局变量;
为什么尽量不使用全局变量,尤其是python编程?正如前面章节介绍到python的变量的时候,我们介绍到一个常量的概念,python的常量实际上没有c/c++那么严格的声明格式语法,通常只是约定俗成的,用大写字母的字符串表示,而它实际上是可以被修改的,可以被轻而易举修改的,这就是问题所在。全局变量也是如此,它可能会在我们写代码的过程中不经意地被修改,或被重新赋值,从而导致程序出现问题,更麻烦的是这种不是bug的bug很难发现,因为它们一般不会被python程序报错,debug也调试不出来,这个时候,程序员就得自个去阅读代码,一行一行地去找,很麻烦。
全局变量示例
In[1]:
var_a = 1 #声明全局变量,可以在函数内部使用
def y():
x=0
x += var_a
return x
print(y())
1
如何跨文件使用全局变量
跨文件,比如a.py文件中的程序要使用b.py文件中的全局变量,那么该怎么办呢?很简单,在使用前用import导入该文件,比如import math,import views(这个在Django的实战开发中会经常遇到)
局部的局部变量
比如:函数体内还有一个函数,其有效范围与上面所介绍的局部变量和全局变量的原理是一样的,比如最外层声明的变量相当于第二层及第二层以上的层级的“全局变量”,以此类推。不过,一般不这么设计函数,麻烦!
如何在函数作用域内修改全局变量
可以用global关键词,global可以用于声明此处的变量是引用外部的全局变量,有点像c/c++的指针的样子:
示例
In[1]:
var_z = 1 #声明一个全局变量
def z():
var_z += 1
retrun var_z
print(var_z()) #程序会发生错误
...
UnboundLocalError: local variable 'var_z' referenced before assignment
def zz():
global var_z
var_z += 1
return var_z
print(var_z) #全局变量被修改
2
作用域综合示例
In[1]: a = 1 #全局变量
def loc():
a = 2 #局部变量
return a
print(a)
1
print(loc())
2
示例解析
虽然局部变量名与全局变量名是一样的,但是它们是两个完全不同的变量,从它们的值便可直观地看出来,大家也可以分别在函数外部和函数内部用print(id(a))来分别打印出这两个变量的内存地址,所得的结果会是不一样的。
python的变量作用域就暂且介绍到这里,后面若是有遇到其他的知识点会进一步详细介绍,下一章节我们将介绍一下递归函数,这个在算法开发当中会遇到。