1.  
  2. 主页
  3.  / 
  4. Python基础到高级
  5.  / 
  6. 函数
  7.  / 
  8. 作用域

作用域

作用域

作用域是一个变量的可见范围叫做这个变量的作用域

>>> x = 1   定义在全局作用域中
>>> def inc():   函数内部是一个局部作用域,是不能直接使用全局作用域的变量
...     x += 1
... 
>>> inc()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in inc
UnboundLocalError: local variable 'x' referenced before assignment

变量的作用域为定义变量同级的作用域

>>> def fn(): 
...     xx = 1   定义一个局部变量,在只能在函数体内部使用
...     print(xx)
... 
>>> fn()
1
>>> xx   局部变量只能在同级的变量作用域中使用,也可以说是,局部变量不能在全局作用域中使用
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'xx' is not defined

>>> def fn1():
...     print(xx)   局部作用域中定义的变量,只能在当前局部作用域使用,不能再其他的局部作用域使用
... 
>>> fn1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn1
NameError: name 'xx' is not defined

函数嵌套演示作用域

>>> def fn():
...     xx = 1
...     print(xx)
...     def inner():   上级作用域对下级作用域可见
...         print(xx)
...     inner()
... 
>>> fn()
1
1

>>> def fn():   上级作用域对下级作用域是只读可见的,下级作用域没有操作上级作用域的权限
...     xx = 1
...     print(xx)
...     def inner():   
...         xx = 2   赋值及定义,在下级作用域里面重新定义了xx变量
...     inner()
...     print(xx)
... 
>>> fn()
1
1

不同作用域变量是不可见的,但是下级作用域可以对上级作用域的变量只读可见

全局变量

定义一个全局变量

>>> xx = 1
>>> def fn():
...     global xx   使用global可以提升变量作用域为全局变量
...     xx += 1
... 
>>> fn()
>>> xx
2

不管在外层有没有定义都可以提升变量作用域,若是有则是提升,若是没有变量,则是定义一个全局变量

>>> def fn():
...     global yy
...     yy = 3
... 
>>> fn()
>>> yy
3

仅仅使用global,是无法单独定义全局变量的

>>> def fn():
...     global zz
... 
>>> fn()
>>> zz
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'zz' is not defined

global 对作用域的提升只对本作用域有用

>>> def fn():
...     global zz   global只能在本作用域生效,如果需要在其他非全局作用域中使用的话,也需要做同样的global提升
...     zz = 3
...     print(zz)
... 
>>> def fn2():
...     zz += 1   这里进行作用域运算时不行的,因为zz只是只读可见的权限,没有操作的权限
...     print(zz)
... 
>>> fn()
3
>>> fn2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in fn2
UnboundLocalError: local variable 'zz' referenced before assignment

>>> def fn2():
...     global zz   要使用其他同级作用域中的global变量,也需要global提升一下
...     zz += 1
...     print(zz)
... 
>>> fn2()
4

除非你清楚的知道global会带来什么,并且明确的知道,非global不行,否则不要使用global

在Python程序中不到非用不可的情况下的话,尽量不要使用global因为global的副作用是很大的,容易造成变量数据的混乱

默认参数的作用域

在Python中一切皆是对象,函数也是对象,函数参数则是函数对象的属性,所以函数参数的作用域会伴随着函数的整个生命周期

>>> def fn(x=[]):   当函数没有释放内存的时候,那么当前函数的生命周期就没有结束,参数则会持续添加
...     x.append(1)
...     print(x)
... 
>>>fn()
[1]
>>> fn()
[1, 1]
>>> fn()
[1, 1, 1]

>>> fn.__defaults__   在函数的生命周期内,函数的默认参数都会保存在__defaults__方法中,元组的形式存储,根据参数的位置存储
([1, 1, 1],)

对于全局作用域里面的函数,初始化的几种方式:

  • 重新定义函数
  • del删除杉树
  • 程序结束退出

对于局部作用域里面的函数,初始化的几种方式:

  • 重新定义函数
  • del 删除函数
  • 上级作用域被销毁

当使用可变类型作为默认参数默认值时,需要特别注意

通常使用一个可变类型作为默认参数时,会使用None来代替

尽可能使用不可变类型作为默认参数的默认值

这篇文章对您有用吗?

我们要如何帮助您?

发表评论

您的电子邮箱地址不会被公开。