局部变量
定义
- 局部变量是在函数内部定义的变量,只能在函数内部使用,或者说,局部变量只能在其被初始化的那个函数内使用。
- 函数执行完成后,函数内部的局部变量,会被系统回收
- 不同的函数,可以定义相同的名字的局部变量,但是彼此之间不会产生影响
创建局部变量
通常,我们在函数的内部声明一个变量以创建一个局部变量
#创建局部变量
def f():
#局部变量s
s = 100
print(s)
使用局部变量
局部变量只能在作用域内使用,函数内部定义的局部变量只能在函数内使用,不能在函数外使用:
不同函数内部的相同名称的局部变量
不同函数内部的相同名称的局部变量互不影响,因为他们只是名字相同:
def f1():
score = 100
print(score)
def f2():
score = 1000
print(score)
全局变量
全局变量,顾名思义,就是全局都可以使用的变量。一般定义在函数之外,并且可以在整个程序中访问:即任何函数的里面或者外部。
#全局变量
score = 1010
#函数内部使用全局变量
def f():
#函数内部没有定义score,但是可以直接用到外部的score
print('内部%s'%score)
#调用函数f
f()
#函数外部使用全局变量
print('外部%s'%score)
函数内部存在一个与全局变量同名的局部变量
现在,如果有一个函数内部存在着一个和全局变量同名的局部变量,他们会怎样互相影响?如果我们在函数内部改变这个局部变量,会影响全局变量吗?
#函数内部的局部变量score
def f():
score = 100
print(score)
#全局变量
score = 1
所以全局变量与局部变量同名时,函数内部使用的是自己的(局部变量),外部使用的是全局的。实际上,函数内部score=100
,这是一个变量的创建语句。
但是有一个问题就是,在函数内部只能访问全局变量,不能修改全局变量:
#全局变量
score = 100
#函数内访问全局变量
def f1():
print(score)
#函数内修改全局变量
def f2():
score = score + 1
print(score)
这种情况下,需要使用global关键字
关键字global
在Python中,global
关键字允许您在当前作用域之外修改变量。
global
被用来在一个非全局范围(比如函数内就是非全局范围)创建一个全局变量。global
关键字常常被用在函数内,这时我们想要修改或者赋值一个函数外的变量(全局变量)。函数内部访问/输出全局变量不需要使用global
Python中global
关键字的基本规则是:
- 当我们在函数内部创建变量时,默认情况下它是局部的。除非使用
global
显示的声明。 - 当我们在函数外部定义变量时,默认情况下它是全局的。您不必使用
global
关键字。 - 我们使用
global
关键字在函数内部使用全局变量。
函数内访问全局变量
#全局变量
a,b = 10,20
def f():
#函数内访问全局变量不需要global
c = a + b #对a,b全局变量的访问,c则是局部变量
print(c)
#调用f()
f()
函数内部修改全局变量
函数内部直接修改全局变量是不行的,这就需要使用到global
关键字:
score = 100
def f():
#score在函数内并没有创建,表示使用的是全局score,会报错
score = score + 10
print(score)
f()
因为是在函数内部修改score
变量,python会假设我们已经有了一个局部变量score
,但是它并没有找到创建score
的语句,所以会报错。为了告诉python,我们使用的是外部的score
,需要使用global
关键字。
这里要了解一下变量的搜索scope的顺序:LEGB】
使用global
关键字之后
score = 100
def f():
#使用global
global score
score += 100
print(score)
f()
原因解释如下:
函数内部的score
直接被拿来修改值,python在局部作用域中没有找到它的定义语句,接着去全局作用域找,找到了score = 100
,但是这个是全局变量,我们没有使用global
关键字,python认为你需要的不是这个变量,接着再去built-in 作用域
找,还是找不到。
最后,python就认为你没有定义score
,但是却拿来直接用了,所以它认为你在一个变量赋值(定义/创建)之前【赋值语句就是创建变量的一种形式】就引用它,就报错了。
看几个例子:
python 不像C/C++
,java
那样,可以在使用变量之前,声明类型,以及变量名,同时又没有赋值给变量,python中变量的创建于赋值是一起的,a = 10
,就可以认为是对变量的定义,不过定义的时候给了值。
def f():
print(s)
s = 100
print(s)
#全局变量
s = 1
print(s)
f() #这里会报错
函数外有一个全局变量s
,函数有一个局部变量s
在代码执行到函数内时,print(s)
,python认为这个局部作用域(local scope)中有一个局部变量s
,接着在局部作用域中找s 的创建/定义语句,然后在下一行就找到了s= 100
,但是这就出了问题,因为你在一定变量创建之前就访问它,这是行不通的,所以它给出的错误是:
UnboundLocalError: local variable 's' referenced before assignment
局部变量 s 在赋值之前就引用它
它是找不到全局作用域的,因为在局部中找到了变量创建语句,只是顺序不对。
分割线----------------------------------------------------------------------------------------------------
再看下面这个:
def f1():
s = s+1
print(s)
s = -1
f1()#这里出错
#函数f1()
内部直接要修改s
,python 认为s
是局部变量,但是函数内没有找到s
的创建语句,然后在全局变量中找到了s
,但是不使用global
,不能修改这个全局s
,所以python认为你用的不是这个全局s
。最后哪里都找不到,所以只能认为你是提前使用这个变量,也就是在它创建之前就使用它。所以它给出的错误是:
UnboundLocalError: local variable 's' referenced before assignment
分隔线-----------------------------------------------------------------------------------------------------
这个
def f():
s = 100
s += -1
print(s)
s = 1
print(s)
f()
函数f()
内有s = 100
,也有全局变量s = 1
,
在函数内s = 100
,python并不会认为这是在使用全局的s
,因为s = 100
是一个变量的创建语句,python认为这是在函数内创建了一个s
的局部变量,因为它找了创建变量的语句啊。所以函数内就是使用这个局部变量s
。
分隔线-----------------------------------------------------------------------------------------------------
函数内使用global 声明为全局变量
在定义函数时 ,使用global
关键字创建函数内的变量时,如果你想在以后再次用到它,使用global
之后就是全局变量了:
def f():
global x #函数内声明x为全局变量,以后可以接着用
x = 100
print(x)
print('222')
f()
#想使用f()内部定义的全局变量x
x = x+1
print(x)
另外:在使用 global
关键字修饰变量名时,不能直接给变量赋初值,否则会引发语法错误。global score = 1
是错误的。
如果全局变量与局部变量同名,则在函数内会优先使用局部变量中的值:
赋值语句就是直接创建一个变量了,但是如果你没有赋值语句,直接想要修改这个变量值,就会报错,还要注意报错的类型。
参考:
Python中的global关键字,你了解吗?
Global and Local Variables in Python