python基础语法6 名称空间与作用域
目录:
1、函数对象
2、函数嵌套
3、名称空间
4、作用域
函数是第一类对象
1、函数名是可以被引用:
def index(): print('from index') a = index a()
2、函数名可以当做参数传递
def foo(x,y,func): print(x,y) func() def bar(): print('from bar') foo(1,2,bar) 结果: 1 2 from bar
3、函数名可以当做返回值使用
传参的时候没有特殊需求,一定不要加括号,加括号当场执行了
def index(): print('from index') def func(a): return a a=func(index) print(a) # <function index at 0x0000000000451E18> a() # from index
4、函数名可以被当做容器类型的元素
def func(): print('from func') l1 = [1, '2', func, func()] # 参数里有函数名和括号,直接运行, 输出from func f = l1[2] print(f) # <function func at 0x0000000001D01E18>
def register(): print('register') def login(): print('login') def shopping(): print('shopping') def pay(): print('pay') func_dic={'1':register,'2':login, '3':shopping,'4':pay } def main(): while True: print(""" 1.注册 2.登陆 3.购物 4.付款 5.退出 """) choice = input("请输入对应的编号:").strip() if choice=='5': break if choice not in func_dic: continue else: func_dic[choice]() main()
函数的嵌套调用:在函数内调用函数
def index(): print('from index') def func(): index() print('from func') func()
def func1(x,y): if x>y: return x else: return y def func2(x,y,z,a): result=func1(x,y) result=func1(result,z) result=func1(result,a) return result print(func2(1,2,454,7)) #454
函数的嵌套定义:
def index(): def home(): print('from home') home() index() #from home
名词空间
什么是名称空间?
存放名字的空间
如果你想访问一个变量值,必须先方向对应的名称空间,拿到名字和对应的内存地址的绑定关系
名称空间的分类:
1、内置名称空间:
python提前给你的定义完的名字,就是存在内置名称空间
2、全局名称空间
存放于文件级别的名字,就是全局名称空间
if while for 内部定义的名字执行之后都存放于全局名称空间
3、局部名称空间
函数内部定义的所有名字都是存放于当前函数的内置名称空间
生命周期:
1、内置名称空间
在python解释器启动的时候生效,关闭解释器的时候失效
2、全局名称空间
当你启动当前这个py文件的时候生效,当前页面代码执行结束之后失效
3、局部名称空间
当你调用当前函数时生效,函数体最后一行代码执行结束就失效
def index(): x = 1 # return x print("index1",index) #全局空间打印全局空间函数 index1 <function index at 0x0000000002061E18> def foo(): print("index2",index) #局部空间调用全局变量 index1 <function index at 0x0000000002061E18> foo() print(print) #全局空间打印内置空间函数 <built-in function print> def index(): print(print) #局部空间打印内置空间函数 index() # <built-in function print>
if 1 == 1: x = 1 #全局空间 print(x) while True: a = 2 break print(a) #全局空间 for i in range(2): print(i) print(i) # 1 打印最后一个i值
名称空间的查找顺序:
局部:局部 > 全局 > 内置
全局:全局 > 内置 # 内置再找不到就报错
函数内部使用的名字,在定义阶段已经规定死了,与你的调用位置无关(变量在局部内,函数嵌套关系会寻找上层;如果是函数互相调用,变量与其他函数变量无关)
x = 111 def func1(): x = 222 def func2(): x = 333 def func3(): # x = 444 def func4(): # x = 555 print(x) #调用嵌套最近的x,也就是x=333 print('from func4') func4() func3() func2() func1() # 333
x = 1 def wrapper(): x = 2 index() def index(): # x = 3 print(x) #找不到x,去全局变量找 wrapper() # 1
x = 1 def inner(): x = 2 def wrapper(): print(x) wrapper() inner() # 2
x = 1 def index(arg = x): # 定义的时候,arg就被赋值了1 print(x) print(arg) x = 2 index() ''' 2 1 '''
x = 111 def index(): def wrapper(): print(x) return wrapper # return wrapper index() x = 222 f = index() f() # 222
作用域的分类:
1、全局作用域
全局可以调用的名字就存在于全局作用域
内置名称空间+全局名称空间
2、局部作用域
局部可以调用的名字就存放与局部作用域
局部名称空间
global:声明全局变量(***)
nonlocal:在局部名称空间声明局部变量,在局部修改上层函数的变量(*)
只有可变类型可以在局部修改外部变量的值 (*****)
错误案例:
b=2 def bar(): b+=3 # 报错,此处无法修改全局变量,但可以查询,如a=b return b print(bar())
x=1 def index(): global x # 不可以写 global x =2 x=2 index() print(x) #2
x=111 def index(): x=1 def func2(): x = 2 def func(): nonlocal x #局部变量关联上层,修改上层局部变量x x = 3 func() print(x) # 3 func2() print(x) # 1 index() print(x) # 111
# 局部变量的修改无法影响上层,上上层
def index(): x=1 def index2(): nonlocal x x=2 index2() print(x) index()
**可变类型可以在局部修改外部变量的值
l1=[] def index(a): l1.append(a) print(l1) #[[...]] index(l1) print(l1) #[[...]]
def func1(): l1=[1,2,3,4,5] def func2(): l1.append(6) return func2() print(l1) # [1, 2, 3, 4, 5, 6] func1() print(l1) # [8, 8, 8]