#名称空间、作用域、加载顺序
"""
内置名称空间:Python定义函数,最先加载
全局名称空间:程序运行时加载
局部名称空间:函数执行时加载,执行结束关闭
内置和全局名称空间是全局作用域
局部名称空间是局部作用域
取值顺序是:局部空间→全局空间→内置空间
"""
name = 'Jerry'
names = 'Jerry'
print(id(name), id(names))#两个变量id相同,因为Python赋值时,会在内存中开辟一个空间,存放变量与值的关系(名称空间)
a = (1, 2, 3)
b = (1, 2, 3)
print(id(a), id(b))#内存id相同
a = [1, 2, 3]
b = [1, 2, 3]
print(id(a), id(b))#内存id不同,因为可变数据类型会重新开辟值内存空间存放变量值
def Test1():
name1 = 'haha'
print(name1, name)
#global 创建、使用全局变量
#创建
def Test4():
global test4
test4 = 'test4'
Test4()
print(test4)#test4
#使用
test2 = 'test'
def Test2():
global test2#不能省略
test2 = 'test2'
Test2()
print(test2)#test2
#**重点**,可变数据类型,函数对全局变量进行操作时不需要global
test3 = [1, 2, 3]
def Test3():
test3.append(4)#不需要global
Test3()
print(test3)#[1, 2, 3, 4]
#nonlocal: 1、不能改变全局变量
"""
报错:
test5 = 'test'
def Test5():
nonlocal test5
print(test5)
Test5()
"""
#2、在局部变量中,对父级作用域(或更外层非全局作用域)变量进行引用和修改
#并且引用的哪层,从哪层及以下此变量发生改变
def Test6():
test6 = 'test6'
print(test6)#test6
def Test7():
print("Test7_1", test6)
def Test8():
nonlocal test6
test6 = 'test8'
print('Test8', test6)#test8 从此处发生变化
Test8()
print('Test7_2', test6)#test8
Test7()
print('Test6', test6)#test8 变量值保持被改变后的值
return test6
print(Test6())#test8 改变的变量值被返回
#3、局部只能引用全局变量,不能修改
a = 1
def test10():
#a = a + 1#报错
print(a)
test10()
#想要修改需要global声明全局
def test11():
global a
a = a + 1
print(a)
test11()
#局部变量同理,需要用nonlocal声明
def test12():
b = 1
def inner():
nonlocal b
b = b + 1
print(b)
test12()
#作用域
test = 5
def F():
def F1():
test = 1#局部变量且没有return
def F2():
nonlocal test#引用外部函数的局部变量,所以用的是上层F() 的test
print('F2内部', test)#4
test = 2
def F3():
global test#引用全局变量,所以用的是函数外的test
print(test)#5
test = 3
test = 4
print(test)#4
F1()
print('F1', test)#4
F2()
print('F2', test)#2
F3()
print('F3', test)#2,F3函数改变了全局变量,但本次输出的变量是F()内的test
F()
print(test)#3