# 函数的命名空和作用域 #命名空间 有三种 # 内置命名空间 --- python解释器 # 就是python解释器,一启动就可以使用的名字存储在内置命名空间中 # 如print(),input()等等.... # 内置的名字在启动解释器的时候被加载进内存中 # 全局命名空间 --- 编写的代码,但不是定义函数中的代码 # 是在程序从上到下被执行的过程中依次加载进内存的 # 放置了我们设置的所有变量名和函数名 # 局部命名空间 --- 函数 # 就是函数内部定义的名字 # 当调用函数的时候,才会产生这个名称空间,随着函数执行的结束,这个命名空间就消失了 # 在局部:可以使用全区、内置命名空间中的名字 # 在全局:可以使用内置命名空间的名字,但是不能使用局部中的名字 # a = 1 # def test(): # def test(): # a=1 # print(a) # print(a) # # test() # test() # print(a) # 在内置:不可以使用全局和局部命名空间的名字:因为它在解释器启动的时候已经开始使用,不依赖用户编写的代码进行启动。 # 依赖倒置原则:内置命名空间A包含全局命名空间B,全局命名空间B里包含局部命名空间C; # 即:A>B>C,A为底层,B为中间层,C为上层,c可以从A,B取值,B能取A的值取不了C的值,A取不了BC的值 # 在正常情况下,直接使用内置的名字 # 当我们在全局定义了和内置名字空间中同名的时候,会使用全局的名字 # 当本身有的时候,就不找上级的要。 # 如果自己没有,就向上级要 # 如果自己没有,就找上级要,上级没有再找上级,如果内置命名空间没有,就报错 # 多个函数应该拥有多个独立的局部命名空间,且互不关联 # def max(): # print(" in max now") # # print(max()) #进Debug模式查看运行顺序 # def input(): # print('in input now') # # def test(): # input() # # test() # 作用域 #只有两种 #全局作用域 --- 作用在全局 --- 内置和全局名字空间中的名字都属于作用域---globals(),查看全局域中有什么名字,仅查看,无论放哪里,都时查看全局的。 #局部作用域 --- 作用在局部 --- 函数(局部名字空间中的名字属于局部作用域)---locals(),查看作用域中有什么名字,仅查看,如果放在全局,则查看全局的。 # 对于不可变数据变类型,在局部中是可以查看全局作用域中的变量 # 但是不能直接修改 a = 1 def test(): a =2 return a a = test() print(a) # 如果需要修改,需要函数开始时进行global声明 #如果在一个局部函数内生命了一个global变量,那么这个变量在局部的所有操作将对全局的变量有效 # a = 1 # def test(): # global a # a += 1
# 函数的嵌套定义
#内部函数可以使用外部函数的定义
# def test():
# a = 1
# def other():
# b =2
# print(a)
# print('other')
# def other1():
# print(a,b)
# print('other1')
# other1()
# other()
#
# print(test())
# nolocal: 只能用于局部变量。找上层中离当前函数最近一层的局部变量
# 声明了nolocal,的内部函数的变量修改会影响到离当前函数最近一层的局部变量
# 对全局无效,对最近一层的局部变量有效
# 对比global,只能修改全局变量的值
# a =1
# def test():
# a = 1
# def other():
# b =2
# print(a)
# print('other')
# def other1():
# nonlocal a # 声明了一个上面第一层局部变量
# a += 1
# print('other1')
# other1()
# other()
# print('局部A:',a)
# print(test())
# print('全局a :',a)
#
# def test():
# print(123)
#
# #test() # 函数名就是内存地址
# test1 = test # 函数名可以赋值
# print(test1,test)
#
# l = [test, test1] # 函数名可以作为容器类型的元素,如列表,元祖,字典等里的元素
# print (l)
# for i in l:
# i()
# def test():
# print(123)
#
# def test_one(t):
# t()
# return t # 函数名可以作为函数的返回值
#
# test_one(test) # 函数名可以作为函数的参数
# a = test_one(test) # 都是指向123的内存地址
# a()
# 闭包: 嵌套函数,内部函数要调用外部函数的变量
# 如果嵌套函数不调用a,则只是一个嵌套函数
# def test():
# a = 1
# def tset_a():
# b = 2
# print(a)
# print(b)
# def test():
# a = 1
# def test_a():
# print(a)
# return test_a
#
# aa = test()
# aa()