闭包函数
1.函数对象
定义:把函数的内存地址当做一种变量值一样去使用------函数对象
函数对象的引用一共有4种,分别是:
1.直接将函数名赋值给一个变量:
def func1(): print('from func1') func2=func1 func2() 此时我的func2这个变量的值便是func1这个函数的内存地址,
我在func2后面加个括号就等于对func1加上了括号,只是此
时调用的方式不一致,这种方法在后面的装饰器部分也又用到。
这个代码的运行结果是: from func1
2.可以当做参数传给另外的函数:
def func1(): print('from func1') def bar(xxx): # print(xxx) xxx() bar(func1) 如上述代码,在调用bar函数时,我们传入了另外一个函数func1,
在bar函数中,我们既输出了传入函数对象既func1的内存地址,
也对存入的函数对象进行了调用,最终结果为: <function func1 at 0x000001DB32915598> from func1
3.可以当做一个函数的返回值:
def func1(): print('from func') def bar(): return func1 f=bar() f()
4.可以当作容器类型的元素:在选择功能的时候可以使用这种方式,技能方便修改,也能减少代码量。
ef register(): print('注册') def login(): print('登陆') def shopping(): print('购物') def pay(): print('支付') func_dic={ '1':register, '2':login, '3':shopping, '4':pay } while True: print(""" 0 退出 1 注册 2 登陆 3 购物 4 支付 """) choice=input('>>>: ').strip() if choice == '0':break if choice in func_dic: func_dic[choice]() else: print('输入错误的指令')
2.函数的嵌套
函数的嵌套分为两种:函数的嵌套调用 和 函数的嵌套定义
1.函数的嵌套调用:在函数内调用了其他函数
def max2(x,y): if x > y: return x else: return y def max4(a,b,c,d): res1=max2(a,b) res2=max2(res1,c) res3=max2(res2,d) return res3 上述代码,使用了函数的嵌套调用的思想,当我们需要解决一
个比较4个数大小的需求时,我们可以将它分成很多的小问题,
在此场景中,我们定义了一个比较2个数大小的函数,在需要完成
比较4个数的大小时,便可以在函数中调用max2函数以解决这个问题。
2.函数的嵌套定义:在函数内定义了其他函数
from math import pi def circle(radius,mode=0): def perimiter(radius): return 2 * pi * radius def area(radius): return pi * (radius ** 2) if mode == 0: return perimiter(radius) elif mode == 1: return area(radius) 我们将求圆的周长与圆的面积的函数定义在了一个大 函数circle中,只需要选择在circle函数中传入的参数 我们就可以选择我们需要调用的函数。
3.名称空间
定义:存放名字与内存地址绑定关系的地方
名称空间分为三类:
1.内置名称空间:存储解释器自带的一些名称与值的对应关系
(python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)
2.全局名称空间:只要你的名字的定义是顶着最左边写的就在全局空间(如果if顶级,那么if中的变 量名也属于全局名称空间)(执行py文件创建全局名称空间 关闭解释器时 销毁)
3.局部名称空间:只要是函数内的名称就是局部的
(调用函数时创建 函数执行完毕就销毁)
名称空间的加载顺序:内置的 -> 全局的 -> 局部的
名称的查找顺序:从当前位置往外一层一层的查找
如果当前处于局部名称空间:当前位置所在的局部----->全局------->内置
如果当前处于全局名称空间:全局------->内置
4.作用域
定义:域指的是区域,范围的的意思.。作用域就是名称空间的范围
作用域的分类:1.全局作用域 2.局部作用域
1.全局作用域:包含内置与全局名称空间的名字 特点:全局存活,全局有效
2.局部作用域:包含局部名称空间的名字 特点:临时存活,局部有效
特别注意:作用域的关系在函数的定义阶段就已经存在固定死了,与调用位置无关!!!
def f1(): print(xxx) xxx=111 def f2(): xxx=222 f1() f2() 调用函数f2时,这个代码的运行结果为111,因为在函数定义时,
f1中有一个print(xxx),但是在f1函数这个局部作用域中并没
有xxx这个变量,所以它会向外部(全局作用域)中区寻找,返现
xxx=111,所以在调用f2时,输出结果会是111,因为在函数定义的时候已经固定死了
5.global 和 nonlocal 关键字
global:在局部变量声明变量是全局变量,声明后再局部变量中可以修改全局变量
def f1(): print(xxx) xxx=111 def f2(): glocal xxx xxx=222 f1() f2() 此时在f2中声明xxx为全局变量后,就可以对xxx进行修改,此时xxx=222就是全局变量,因此输出为222
nonlocal:在局部变量中声明变量是外层函数变量(永远都不会找到全局变量中)
6.闭包函数
定义:闭函数:该函数一定是定义在函数内的函数
包函数:该内部函数包含对外层函数作用域名字的引用
闭包函数模板:
def outter(): x=10 def inner(): print(x) return inner
闭包函数也可以为函数体传值:
def outter(x): def inner(): print(x) return inner