全局变量与局部变量两者的本质区别就是在于作用域
用通俗的话来理解的话,
全局变量是在整个py文件中声明,全局范围内都可以访问
局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就爆掉了
如果在函数内部定义与某个全局变量一样名称的局部变量,就可能会导致意外的效果,可能不是你期望的。因此不建议这样使用,这样会使得程序很不健全
直接来看几个例子来理解全局变量和局部变量的区别吧:
def fun(): f=1 # print(f) print('>>>:',f) fun() print(f)
运行结果:
>>>: 1 Traceback (most recent call last): File "C:/Users/zhang1995/PycharmProjects/day1/day6/day6_txt.py", line 57, in <module> print(f) NameError: name 'f' is not defined
分析:上面的代码中f是局部变量。而且,整个程序中之定义了一个f变量。在函数内和外,都设定了print(f),来输出f.
从运行结果可以看出。在函数内的print正常执行。print-->1。而外面的print 程序报错,错误原因是:f变量没有定义。所以可以看出,print是无法引用函数里的变量。
# f =100 # def fun(): # f=1 # # print(f) # def fun1(): # # f=0 # # print('---:',f) # print('>>>:',f) # fun1() # print(f) #如果函数内没有f变量,就向全局变量中寻找,如果有,就输出f # fun() # print(f) #下级局部变量空间没有要引用的值,就向上级空间寻找,但是上级空间不能向下级空间寻找
>>>: 1 1 100
可以看出:从fun1函数内:当f=0时:print(>>>:)输出的值就是:0.
当fun1内的f没有被定义时,就会去fun1的外部变量域中去寻找。而当f=1存在,所以print(>>>:)输出的就是:1
但是,当在fun中没有f =1时,就会去全局中去寻找,而全局中有f=100,所以,print('>>>"):100。
在Python中,当引用一个变量的时候,对这个变量的搜索是按找本地作用域(Local)、嵌套作用域(Enclosing function locals)、全局作用域(Global)、内置作用域
(builtins模块)的顺序来进行的,即所谓的LEGB规则。 然而当在一个函数内部为一个变量赋值时,并不是按照上面所说LEGB规则来首先找到变量,之后为该变量赋值。在Python中,在函数中为一个变量赋值时,有下面这样一条规则: “当在函数中给一个变量名赋值是(而不是在一个表达式中对其进行引用),Python总是创建或改变本地作用域的变量名,除非它已经在那个函数中被声明为全局变量. ”'''
所以在嵌套作用于中有可能出现的坑:看下面代码:
def fun(): num2 = 3 def fun2(): num2 *= 2 #当对fun的变量num2进行修改的时候,就还会把num2当作fun2的变量。但是 #fun2中没有定义num2,所以无法进行修改 print("num2=", num2) #如果是简单的引用,就不会发生判定变量属于下载的变量域 fun2() fun()
发生这种情况就得用到:关键字nonlocal
def fun(): num2 = 3 def fun2(): nonlocal num2 num2 *= 2 print("num2=", num2) # print(num2) fun2() fun()
num2= 6
用了nonlocal关键字,就会告诉Python在fun2函数中使用嵌套作用域中的变量num2,因此对变量num2t进行修改时,会直接影响到嵌套作用域中的num2变量,程序最后也就输出6了.
注意:使用global关键字修饰的变量之前可以并不存在,而使用nonlocal关键字修饰的变量在嵌套作用域中必须已经存在。