面试高频题
面试官通常会问: 1. python 装饰器的作用是什么? 2. 装饰器的原理与实现?
考点分析
- 是否使用过Python的一些内置装饰器,或者第三方封装的装饰器。
- 是否了解装饰器的使用场景,是否有自己封装装饰器并使用。
总结
- 本质是封装了一个闭包函数,在函数、方法或者类的定义上方添加 @装饰器名称 进行使用。
- 优化代码的可读性,可维护性
装饰器:在函数体开始执行与结束执行时分别添加打印信息。
装饰器的执行步骤如下:
def zz():
print("测试1")
def cc():
print("测试2")
# 封装'开始执行-某个方法-结束执行'
def fun_tips(func):
print("开始执行")
# 不再写死任何一个函数,传入任意外部函数对象
func()
print("结束执行")
# 传入函数对象'某个方法'
fun_tips(cc)
# 这段代码打印结果是:
开始执行
测试2
结束执行
添加一个装饰器的步骤
- 第一步,定义两个函数,一个内函数,一个外函数;外函数有一个形参,接收被装饰的函数对象;
- 第二步,在内函数中添加装饰器逻辑;
- 第三步,把内函数的函数对象return出去,这里return要注意在外函数那层,return值的格式为内函数对象;
- 第四步,装饰器的使用,@外函数名;
- 第五步,在装饰器执行过程中,会自动传入一个参数,参数就是被装饰函数的函数对象;
- 第六步,添加被装饰函数的执行步骤;
def timer(func):
def inner():
# 内函数,执行装饰器逻辑
print("开始执行")
func() # 添加被装饰函数的执行步骤
print("结束执行")
return inner
# 装饰器的使用@+外函数名
@timer
def zz():
print("测试1")
练习:写一个计时器,计算函数的执行时间
import datetime
def timer(func):
def inner():
"""
装饰器逻辑的实现
:return:
"""
start_time = datetime.datetime.now()
func()
end_time = datetime.datetime.now()
print(f"函数的执行时间为{end_time-start_time}")
return inner
@timer
def module():
print("模块")
module()
打印结果为:
模块
函数的执行时间为0:00:00.000330
基于上面的计时器,存在两个问题
Q1:被装饰的函数如果存在传参,如何处理?
A1:在内函数加形参,在函数调用的地方添加参数信息
Q2:如果被装饰的函数需要写死参数,但是不确定参数数量
A2:把内函数形参和函数调用的地方形参换成不定长参数即可
import datetime
def timer(func):
def inner(*args, **kwargs):
"""
装饰器逻辑的实现
:return:
"""
start_time = datetime.datetime.now()
func(*args, **kwargs)
end_time = datetime.datetime.now()
print(f"函数的执行时间为{end_time-start_time}")
return inner
@timer
def module1(name):
print(f"模块{name}")
@timer
def module2(name, age, gender):
print(f"模块2{name, age, gender}")
module1("zz")
print("==================")
module2("cc", "男", "10岁")
print("==================")
module2("jj", "女", "1岁")
print("==================")
打印结果如下:
模块zz
函数的执行时间为0:00:00.000064
==================
模块2('cc', '男', '10岁')
函数的执行时间为0:00:00.000016
==================
模块2('jj', '女', '1岁')
函数的执行时间为0:00:00.000008
==================
面试高频题
面试官通常会问: 1. python 装饰器的作用是什么? 2. 装饰器的原理与实现?
考点分析
- 是否使用过Python的一些内置装饰器,或者第三方封装的装饰器。
- 是否了解装饰器的使用场景,是否有自己封装装饰器并使用。
总结
- 本质是封装了一个闭包函数,在函数、方法或者类的定义上方添加 @装饰器名称 进行使用。
- 优化代码的可读性,可维护性
网友评论