python面试题No2
作者:互联网
1. python装饰器 ?
装饰器本质上是一个Python函数.
在不改变源代码,不改变调用方式的情况下给其他函数或者类添加额外的功能. 装饰器的返回值也是一个函数对象。
应用场景:插入日志、性能测试、事务处理、缓存、权限校验等。有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续复用。
根据函数是否传参 是否有返回值 ,可以分析出装饰器的四种形式:
形式一:无参无返回值
1 def outer(func): 2 def wrapper(): 3 print("装饰器功能1") 4 ret = func() 5 print("装饰器功能2")
return ret 6 return wrapper 7 8 # 定义一个无参无返回值的函数 9 @outer 10 def main_func(): 11 print("hello") 12 13 main_func() # 开始执行 14 15 16 结果如下: 17 装饰器功能1 18 hello 19 装饰器功能2
总结: 装饰器功能1 装饰器功能2 可以根据具体项目需求需要的附加功能来写具体代码,可以在原功能函数之前,也可以在其之后
形式二:无参有返回值
1 def outer(func): 2 def wrapper(): 3 print("装饰器功能1") 4 ret =func() 5 print("装饰器功能2") 6 return ret 7 return wrapper 8 9 # 定义一个无参有返回值的函数 10 @outer 11 def main_func(): 12 return "hello" 13 14 15 print(main_func() 16 17 18 结果如下: 19 装饰器功能1 20 装饰器功能2 21 hello
总结: 装饰器功能1 装饰器功能2 可以根据具体项目需求需要的附加功能来写具体代码,可以在原功能函数之前,但不能在原功能函数之后
形式三:有参无返回值
1 def outer(func): 2 def wrapper(str1): 3 print("装饰器功能1") 4 ret =func(str1) 5 print("装饰器功能2") 6 return ret 7 return wrapper 8 9 # 定义一个有参无返回值的函数 10 @outer 11 def main_func(str1): 12 print("hello "+str1) 13 14 15 main_func("Python") 16 17 18 结果如下: 19 装饰器功能1 20 hello Python 21 装饰器功能2
总结: 装饰器功能1 装饰器功能2 可以根据具体项目需求需要的附加功能来写具体代码,可以在原功能函数之前,也可以在其之后
形式四:有参有返回值
1 def outer(func): 2 def wrapper(str1): 3 print("装饰器功能1") 4 ret =func(str1) 5 print("装饰器功能2") 6 return ret 7 return wrapper 8 9 # 定义一个有参有返回值的函数 10 @outer 11 def main_func(str1): 12 return "hello "+str1 13 14 15 print(main_func("Python")) 16 17 18 结果如下: 19 装饰器功能1 20 装饰器功能2 21 hello Python
总结: 装饰器功能1 装饰器功能2 可以根据具体项目需求需要的附加功能来写具体代码,可以在原功能函数之前,但不能在原功能函数之后
万能装饰器:
def wrapper(func): # func为被装饰函数
def inner(*args,**kwargs):
"""被装饰函数前需要添加的内容"""
ret=func(*args,**kwargs) #被装饰函数
"""被装饰函数后需要添加的内容"""
return ret
return inner
-
*args :按照位置传值,多余的参数都给args,以元祖的形式存储
-
**kwargs :按照关键字传值,多余的参数个kwargs,以字典的形式存储
2.可迭代对象、迭代器、生成器?
Python可迭代对象(Iterable)
Python中经常使用for
来对某个对象进行遍历,此时被遍历的这个对象就是可迭代对象,像常见的list
, tuple
都是。如果给一个准确的定义的话,就是只要它定义了可以返回一个迭代器的__iter__
方法,或者定义了可以支持下标索引的__getitem__
方法,那么它就是一个可迭代对象。
可迭代对象与迭代器
- 可迭代对象包含迭代器。
- 如果一个对象拥有
__iter__
方法,那么它是可迭代对象;如果一个对象拥有next
方法,其是迭代器。 - 定义可迭代对象,必须实现
__iter__
方法;定义迭代器,必须实现__iter__
和next
方法。
-
_iter_()
该方法返回的是当前对象的迭代器类的实例。因为可迭代对象与迭代器都要实现这个方法 -
next()
返回迭代的每一步,实现该方法时注意要最后超出边界要抛出StopIteration异常。
迭代器Iterator
迭代器就是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()
函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。
实际上,在使用next()
函数的时候,调用的就是迭代器对象的__next__
方法
so 我们要想构造一个迭代器,就要实现它的__next__
方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__
方法,而__iter__
方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__
方法返回自身即可。
一个实现了__iter__
方法和__next__
方法的对象,就是迭代器。
生成器 :
- 生成器是一种特殊的迭代器,生成器
自动
实现了“迭代器协议”(即__iter__
和next
方法),不需要再手动实现两方法。 - 生成器在迭代的过程中可以改变当前迭代值,而修改普通迭代器的当前迭代值往往会发生异常,影响程序的执行。
- 具有
yield关键字
的函数都是生成器,yield
可以理解为return
,返回后面的值给调用者。不同的是return
返回后,函数会释放,而生成器则不会。在直接调用next
方法或用for语句进行下一次迭代时,生成器会从yield下一句开始执行,直至遇到下一个yield
标签:__,面试题,return,迭代,python,功能,func,装饰,No2 来源: https://www.cnblogs.com/longpy/p/11031360.html