瀋凣

V1

2022/03/03阅读:86主题:极简黑

python笔记37

Python day37

1. 函数

1.5 作用域

所谓作用域,就是指变量可以被访问的范围。通常,一个变量的作用域总是由它在代码中被赋值的位置决定的。

1.5.1 局部作用域

如果一个变量定义的位置是在函数内部,那么这个变量的作用域就仅限于该函数中,我们称之为局部变量。

>>> def myfunc():
...     x = 520  #在函数内部定义的变量,局部变量
...     print(x)
... 
>>> myfunc()
520
  • 尝试在函数外访问局部变量x
>>> print(x)  #报错
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
NameError: name 'x' is not defined

1.5.2 全局作用域

如果是在任何函数的外部定义一个变量,那么这个变量的作用域就是全局的,我们称之为全局变量。

>>> x = 886
>>> def myfunc():
...     print(x)
... 
>>> myfunc()  
886  #函数可以访问到外部的变量

当函数内外存在同名变量时,会发生什么呢?

>>> x = 886
>>> def myfunc():
...     x = 520
...     print(x)
...
>>> myfunc()
520  
>>> print(x)
886

我们发现,局部变量会覆盖同名的全局变量。

其实,上例中的全局变量x和局部变量x并不是同一个变量,只是由于作用域的不同,两个变量同名不同样。

  • 当函数内没有同名局部变量时,函数内访问到的x就是全局变量x
>>> x = 886
>>> id(x)
515121817008
>>> def myfunc():
...     print(id(x))
...
>>> myfunc()
515121817008
  • 当函数内存在同名变量时,函数内访问到的x就是和全局变量完全不同的另一个变量
>>> def myfunc():
...     x = 886
...     print(id(x))
...
>>> myfunc()
515121817520

由此可知,全局变量可以在函数的内部被访问到,但是却无法在函数的内部修改它的值。因为一旦试图在函数内进行赋值操作,Python就会立刻创建一个同名的局部变量进行覆盖。

1.5.3 global语句

那么是否就无法在函数内部修改全局变量了呢?
并不是,我们可以通过global关键字来实现在函数内部修改全局变量。

>>> def myfunc():
...     global x  #先用global关键字声明
...     #注意:这里不能写成 global x = 520 这种写法
...     x = 520
...     print(x)
... 
>>> myfunc()
520
>>> print(x)
520

1.5.4 嵌套函数及其变量作用域

函数也可实现嵌套操作。

  • 自定义一个嵌套函数
>>> def myfunA():
...     x = 520
...     def myfunB():
...             x = 886
...             print('in myfunB(),x = ',x)
...     print('in myfunA(),x = ',x)
...     myfunB()
... 
  • 在函数外部,无法调用内层的嵌套函数,内层的函数只能在函数内部被调用
>>> myfunB()
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
NameError: name 'myfunB' is not defined
  • 调用外层函数
>>> myfunA()
in myfunA(),x =  520
in myfunB(),x =  886

从打印结果可知,内层函数可以访问到外层函数的变量,但是无法修改它。

1.5.5 nonlocal语句

如果要修改嵌套作用域(外层非全局作用域)中的变量则需要 nonlocal 关键字。

>>> def myfunA():
...     x = 520
...     def myfunB():
...             nonlocal x
...             x = 886
...             print('in myfunB(),x = ',x)
...     myfunB()
...     print('in myfunA(),x = ',x)
... 
>>> myfunA()
in myfunB(),x =  886
in myfunA(),x =  886

1.5.6 LEGB

变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

规则顺序: L → E → G → B
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。

LEGB规则
LEGB规则
>>> str = 'kill str'
>>> str(520)
Traceback (most recent call last):
  File "<stdin>", line 1in <module>
TypeError: 'str' object is not callable
点点关注不迷路
点点关注不迷路
- END -

分类:

后端

标签:

Python

作者介绍

瀋凣
V1