目录
1.函数嵌套
2.闭包
3.装饰器
这一节,我会详细Python中讲解函数的进阶内容,包括嵌套函数、闭包和装饰器。一起来学习吧!!!
1.函数嵌套
概念:函数里面再定义一个函数
作用:当我们在一个多功能的函数里面想把这些功能进一步去拆分为多个子模块,但是又觉得这些子模块放到全局的话会因为函数的名字冲突而影响程序的整体效果,这时候我们就需要去利用函数的嵌套,在函数里面去定义函数,然后再进行调用,这样可以提高代码的可读性(先定义后调用)
样式:
def fun1():
def fun2():
pass
def fun3():
pass
fun3()
fun3()
示例:
定义一个函数,输入一个数字,先判断这个数字是不是奇数,如果是的话就返回这个奇数的阶乘,如果不是的话就返回0
def fun(n):
def judge():#判断是不是奇数
if n%2==0:
return False
else:
return True
def output(a):#获取上一个函数的返回值,如果是计算就返回计算的阶乘,否则返回0
if a:
sum=1
for i in range(1,n+1):
sum*=i
return sum
else:
return 0
return output(judge())
s=input('输入你的数字:')
print(fun(int(s)))
看!这个就是一个嵌套函数的代码,这让我们觉得这种写法非常明了,一个大模块函数里面包含了多个小模块函数,每个小模块有其相对应的功能,可读性很强,简洁明了。最最最重要的是这个函数里面的子函数名字是作为一个局部变量,完全不会影响到外面的全局变量,就算是外面有与子函数名字相同的变量,结果也是互不影响的。
2.闭包
前面我们都知道函数变量其实是一个具有函数功能的变量,其本质是一种变量类型,所以我们可以去实现函数变量的赋值,进而实现这个被赋值的变量具备了函数的功能,其实闭包就是巧妙地利用了这种关系而形成的一种方法。
在讲之前,先看个示例 :
def fun(time):
print('o(* ̄︶ ̄*)o')
print('全民制作人们,大家好')
print('我是练习时长%s的个人练习生cxk'%time)
user=fun
user('两年半')
#输出结果:
# o(* ̄︶ ̄*)o
# 全民制作人们,大家好
# 我是练习时长两年半的个人练习生cxk
概念:闭包,又称闭包函数或者闭合函数,是基于函数嵌套搞出来一个特殊嵌套。闭包中外部函数返回的不是一个具体的值,而是一个函数。一般情况下,返回的函数会赋值给一个变量,这个变量可以在后面被继续执行调用。
作用:获取保存外部函数的变量,不会因为这个变量随着函数的调用而销毁,然后把外部函数的变量用到内部函数去,最后返回内部函数
#闭包
def outside():
a=100 #这个是一个临时变量,会随着函数被调用之后而销毁
def inside(b):
c=a+b
print(f'输出{c}',end='')
return inside #注意,这里是返回这个函数的变量名,而不是返回整个函数
my=outside()
my(9) #此时变量 my 已经具备了inside() 这个函数的功能
#输出结果:输出109
这个就是很简单的闭包形式,在内函数中利用了外函数的临时变量,同时还具备内函数的功能,最后返回这个内函数变量名字,当我们要去获取这类功能的变量时,我们就可以去直接定义一个变量等于这个outside()函数,以后做项目的时候会经常用到闭包的。
3.装饰器
在讲之前,我先讲一个例子可以帮助我们更好地理解装饰器:当我看到小美有一顶可爱的小白兔 帽子,这时候我也想买跟她一样的帽子去戴到头上,这时候我会去问小美哪里可以买到这顶帽子,这时候小美会告诉我她买的地方,我就会去那个地方买;同样当我买了帽子之后,小叶看到我买了这个帽子,她也会问我去那里买,我也很同样去告诉她……其实这个帽子就可以理解为一个装饰器,而卖帽子的地方可以去看做一个产生装饰器的代码。
概念:本质就是一个函数 , 是一个特殊的闭包,也是函数嵌套的一种表现形式
作用:就是在不修改源代码的前提下,对原有的函数增加新的功能。遵循封闭开放原则:对修改源代码的的操作封闭 , 对增加新的功能的操作开放
限制与统计:
1.不可以修改已有的代码功能
2.不可以修改已有的函数调用方式
3.给一个已有函数增加额外的功能
装饰器与闭包函数区别:
装饰器本质上是一个闭包函数,但是装饰器有且仅有一个参数,同时这个参数的类型还必须是函数类型,这样才满足装饰器的条件,否则那就不是装饰器,而是一个闭包函数
先来看看几个例子:
非装饰器原型(具有装饰器功能):
def out(q): #参数q是一个函数类型的参数
def inside():
q() #执行这个函数
print('fuck')
return q() #最后再次返回这个函数再次执行
return inside #外函数返回内层函数
def kun():
print('蔡徐坤')
print('只因')
a=out(kun)
a()
你们可以去自行看代码,试着想一下结果
以上就是结果,这里可能会有些人觉得懵懵的。这个其实就是装饰器的一个功能原型(但非装饰器),首先是在out()函数传入一个函数类型,然后进入到内层函数来执行,所以我们就看内层函数,这个函数的执行顺序是先执行这个传入的函数,再去打印一个'fuck',然后返回这个传入的函数再次执行,所以结果就是这样而来的。
装饰器写法:
#装饰器的代码
def out(q): #参数q是一个函数类型的参数
def inside():
q() #执行这个函数
print('fuck')
return q() #最后再次返回这个函数再次执行
return inside #外函数返回内层函数
@out #装饰器的使用,等效于kun=out(kun) 即kun=inside,后面直接去使用就行了
def kun():
print('蔡徐坤')
print('只因')
kun()#直接调用这个已经被装饰好了的函数
out()函数就是一个装饰器的代码,当我们要去装饰函数的时候就直接去艾特@就行了,这时候这个函数会传入到装饰器里面去,然后进入到内层函数进行相对应的功能,自然,输出结果也是一样的。
带参数的装饰器
请写一个装饰器可以实现一个带参数的加法函数,然后给每个参数增加阶乘功能,最后返回这些参数阶乘的和
比如:输入 4 和 5
输出:4!+5!的结果
def out(q): #参数q是一个带参数的函数类型的参数
def inside(a,b): #内层函数需要传入被装饰函数的参数值,不然无法在下面去调用这个函数
sum1=1#a的阶乘
sum2=1#b的阶乘
for i in range(1,a+1):
sum1*=i
for j in range(1,b+1):
sum2*=j
q(sum1,sum2)#这里就调用了加法函数,然后输出sum1和sum2的和
return inside
@out #等效于kun=out(kun) 即kun=inside,要用的时候就直接去调用就行了
def kun(a,b):
c=a+b
print(c)
a=int(input('num1:'))
b=int(input('num2:'))
kun(a,b)
这个就是带有参数的装饰器,要注意好参数的类型以及位置,当我们要在传上去里面去传入参数的时候就得取出要装饰的参数部分与之相对应。
在Python中,装饰器的功能是非常强大的,我们去定义函数的时候可以通过装饰器来给这个函数来添加功能,完全不需要去定义另一个函数来实现这些功能,而且装饰器还可以多次使用,随取随用。
送一张壁纸~~