函数的嵌套定义
概念:在一个函数内部定义另一个函数
为什么要有函数的嵌套定义
--1、函数fn2想使用fn1内部的局部变量,可以直接把fn2定义到fn1的内部,这样fn2就可以直接访问fn1内部的变量
--2、函数fn2就变成了fn1的局部变量(名)了,想要在外部调用fn2,可以把fn2函数对象作为fn1的返回值传出去
--3、在外部也可以用fn2同名的变量来接收fn1的执行结果(返回值是fn2),那么fn2就可以在外部被调用了
global关键字
作用:将局部变量提升(声明同步)为全局变量
--1、全局如果没有同名变量,直接提升局部变量为全局变量
--2、全局有同名变量,就直接同步局部变量与全局变量
--如果局部想改变全局变量的值(地址发生改变),那就用global声明该变量
num = 10def fn(): # global num #有了global修饰,num就和外面的全局变量同步起来 num = 20 #没有global修饰,这个num就是自己的一个 print(num) #局部变量,和外面没有影响fn()print(num)
nonlocal关键字
作用:将局部的变量提升(声明同步)为嵌套局部变量
必须要有同名的嵌套局部变量,就是统一嵌套局部与局部的变量
--如果局部想改变嵌套局部变量的值(发生地址改变),可以用nonlocal声明该变量
#注:1、nonlocal只能用于同步局部变量和嵌套局部变量,如果用于同步局部和全局的话就会报错
2、对于一个嵌套局部变量,不可以一边将他同步到全局变量(global)一边同步到局部变量(nonlocal),会报错
开放封闭原则
开放封闭原则:在不修改源代码与调用方式的前提下为函数添加新功能
开放:可以做的事,添加新功能
封闭:不可以做的事,两个原则
--1、不能修改源码 -1.无权修改 2.功能不特有 3.需要一一修改
--2、不能修改调用方式 -修改调用方式的弊端:原项目的所有调用都要修改,成本太高
装饰器
满足开放封闭原则的一个闭包函数的应用
#装饰器的格式def outer(func): def inner(*args,**kwargs): #因为不知道下面函数要穿多少参数,所以用可变长形参以(args)元组,(kwargs)字典全部接收 #添加新的功能 res = func(*args,**kwargs) #再加*号把之前接收到的元组,字典解压给原功能 #添加新的功能 return res return inner@outer ->#这里的@outer是调用装饰器,被装饰的函数名以参数形式传入装饰器的outer()函数里,返回的是内部函数inner函数名def fn(): #这个@outer相当于 fn = outer(fn) = inner pass fn() #后面再调用fn()就相当于调用inner()
总结:1、装饰器执行过程就是用被装饰的函数名给去接收装饰器的执行结果
调用装饰器时传入被装饰的函数对象作为参数
2、表面上用的还是原函数名,其实是原函数名已经被重新赋值为装饰器内部函数名
--所以调用的原函数其实是调用装饰器里的函数(可以在里面添加新功能)
一个函数被多次装饰
如果一个函数被多个装饰器装饰,那么装饰器的调用时从上往下开始调用,但是返回的结果时从下往上一层一层传上去