函数内部的函数只能在函数内部调用,不能在函数外部调用?!
缘由: 名称空间问题!!!python
名称空间(name spaces):在内存管理那一章节时,咱们曾说到变量的建立其实就是在内存中开辟了一个新的空间。可是咱们一直在回避变量名的存储,其实在内存中有一块内存存储变量名与变量间的绑定关系的空间,而这个空间称为名称空间。app
内置名称空间:存放Pyhton解释器自带的名字,如int、float、len函数
生命周期:在解释器启动时生效,在解释器关闭时失效spa
全局名称空间:除了内置和局部的名字以外,其他都存放在全局名称空间,以下面代码中的
x、func、l、z
生命周期:在文件执行时生效,在文件执行结束后失效code
x = 1 def func(): pass l = [1, 2] if 3 > 2: if 4 > 3: z = 3
局部名称空间:用于存放函数调用期间函数体产生的名字,以下面代码的f2对象
生命周期:在文件执行时函数调用期间时生效,在函数执行结束后失效生命周期
def f1(): def f2(): print('from f2') f2() f1()
因为.py文件是由Python解释器打开的,所以必定是在Python解释器中的内置名称空间加载结束后,文件才开始打开,这个时候才会产生全局名称空间,但文件内有某一个函数被调用的时候,才会开始产生局部名称空间,所以名称空间的加载顺序为:内置--》全局--》局部。内存
因为名称空间是用来存放变量名与值之间的绑定关系的,因此但凡要查找名字,必定是从三者之一找到,查找顺序为:
从当前的所在位置开始查找,若是当前所在的位置为局部名称空间,则查找顺序为:局部--》全局--》内置。作用域
x = 1 y = 2 len = 100 def func(): y = 3 len = 1000 print(f"y: {y}") print(f"len: {len}") # print(a) # NameError: name 'a' is not defined func()
y: 3 len: 1000
内存管理
x = 1 def func(): print(x) x = 10 func()
域指的是区域,做用域即做用的区域。
全局做用域:全局有效,全局存活,包含内置名称空间和全局名称空间。
# 全局做用域 x = 1 def bar(): print(x) bar()
1
局部做用域:局部有小,临时存储,只包含局部名称空间。
# 局部做用域 def f1(): def f2(): def f3(): print(x) x = 2 f3() f2() f1()
2
须要注意的是:做用域关系在函数定义阶段就固定死了,与函数的调用无关。
# 做用域注意点 x = 1 def f1(): # 定义阶段x=1 print(x) def f2(): x = 2 f1() f2()
1
# 做用域应用 def f1(): def inner(): print('from inner') return inner f = f1() # 把局部定义的函数放在全局之中 def bar(): f() bar()
from inner
修改全局做用域中的变量.
x = 1 def f1(): x = 2 def f2(): # global x # 修改全局 x = 3 f2() f1() print(x)
1
x = 1 def f1(): x = 2 def f2(): global x # 修改全局 x = 3 f2() f1() print(x)
3
修改局部做用域中的变量。
x = 1 def f1(): x = 2 def f2(): # nonlocal x x = 3 f2() print(x) f1()
2
x = 1 def f1(): x = 2 def f2(): nonlocal x x = 3 f2() print(x) f1()
3
1.在局部想要修改全局的可变类型,不须要任何声明,能够直接修改。
2.在局部若是想要修改全局的不可变类型,须要借助global声明,声明为全局的变量,便可直接修改。
lis = [] def f1(): lis.append(1) print(f"调用函数前: {lis}") f1() print(f"调用函数后: {lis}")
调用函数前: [] 调用函数后: [1]