函数对象
函数是第一类对象:函数名指向的值可以被当做参数进行传递 1.函数名可以被传递 def fnc(): pass print(fnc) # <function fnc at 0x000001622CC81E18> f = fnc print(f) # <function fnc at 0x0000021CF3121E18> 指向的是fnc内部代码体内存地址 2.函数名可以当做参数传递给其他函数 def fnc(): print('clydsb') def fnc1(args): print(args) args() print('cly') fnc1(fnc) <function fnc at 0x0000015663EE1E18> clydsb cly 3.函数名可以当做函数的返回值 def fnc(): print('hello') def fnc1(): print('clysb') return fnc res = fnc1() res() clysb hello 4.函数名可以被当做容器类型的参数 def fnc(): print('clydsb') l = [1,2,3,fnc] # 指向函数内部代码体内存地址 print(l) # 循环打印项目功能提示信息 供用户选择 用户选择谁就执行谁 def register(): print('注册') def login(): print('登入') def tranfer(): print('转账') def pay(): print('支付') msg = ''' 1.注册 2.登入 3.转账 4.支付''' dic = { '1':register, '2':login, '3':tranfer, '5':pay } while True: print(msg) choice = input('请输入你想要的功能>>:').strip() if choice in dic: dic[choice]() else: print('输入指令有误') # 将复杂的代码用函数简单化
函数嵌套调用及定义
在函数内部调用其他函数 将复杂的逻辑简单化 def max_2(a,b): if a > b: return a return b def max_4(a,b,c,d): res1 = max_2(a,b) res2 = max_2(c,d) res3 = max_2(res1,res2) print(res3) max_4(2,3,4,6) 函数的嵌套定义 def fnc(): print('hello') def inner(): print('world') return inner f = fnc() print(f) f() ''' hello <function fnc.<locals>.inner at 0x000001A2FEC998C8> world '''
名称空间作用域
名称空间是什么? 就是存放名字的地方 存放变量名与变量值(的内存地址的)绑定关系的地方 想访问一个变量的值 必须先去名称空间找到对应的名字 才能够访问变量的值 名称空间的分类 内置名称空间 python解释器已经提前定义好一些名字,存入内置名称空间 比如:len print max 全局名称空间 文件级别的代码 x = 1 if x == 1: y = 2 while True: z = 3 x,y,z都会存放在名称空间中 if while for 不管循环嵌套多少层 它们内部创建的名字都会存放在全局名称空间中 局部名称空间 函数体内创建的名字都会传入局部名称空间中 生命周期 内置名称空间 python解释器只要一启动,就会立马创建内置名称空间,关闭python解释器内置名称空间自动销毁 全局名称空间 只要你右键运行python文件就会立马创建全局名称空间,运行结束就会自动销毁 局部名称空间 函数被调用的时候立即创建局部名称空间,函数调用结束会立即销毁(动态创建动态销毁) 名字查找顺序 首先需要确定你在哪个空间中 在全局中,如果全局没有找到会去内置找 print(len) <built-in function len> 在局部中没有找到,会先去全局中找,全局中没有,再去内置中找 def fnc1(): x = 1 def fnc2(): # x = 2 def fnc3(): # x = 3 def fnc4(): # x = 4 print(x) fnc4() fnc3() fnc2() fnc1() 函数嵌套中 嵌套函数首先会在自己的局部空间找 没有找到就往上一层寻找(按嵌套逐层往上寻找,找不到找全局,再找不到就去内置,再找不到报错) 如果变量名命名在调用函数代码下面命名,会直接报错 (NameError: free variable 'x' referenced before assignment in enclosing scope) 函数在定义阶段查找名字的顺序已经固定好了,不会因为函数调用位置的变化而变化(******) x=111 def outer(): def inner(): print('from inner',x) return inner f=outer() def func(): x=333 f() func() 输出结果为111 作用域 全局作用域 全局有效: 内置名称空间 全局名称空间 局部作用域 局部有效 局部作用域 # global nonlocal # global 在局部修改全局的不可变数据类型 # nonlocal 局部修改局部 global x = 1 name = 'jzdsb' def fnc(): global x,name x = 999 name = 'clydsb' print(x,name) nonlocal def fnc(): x = 1 name = 'cly' def fnc1(): nonlocal x,name x = 2 name = 'clydsb' fnc1() print(x,name) fnc()