装饰器、迭代器、生成器
1、装饰器:
装饰器实现原理有两种,一种通过类,主要是通过__call__
class Decorator(object):
"""
这是一个装饰器
"""
def __init__(self, func):
print('---初始化---')
print('func name is %s' % func.__name__)
self.__func = func
def __call__(self, *args, **kwargs):
print('---装饰器的功能---')
self.__func()
# __call__的用法
# class Test():
# def __call__(self):
# print('call me!')
#
# t = Test()
# t() # call me
@Decorator
def test():
print('---test---')
test()
# @Decorator的作用
# test = Decorator(test)
还有一种实现的原理是闭包,Python支持一个叫做函数闭包的特性,嵌套定义在非全局作用域里面的函数能够记住它在被定义时所处的封闭的命名空间
def outer(some_func):
def inner(*args, **kwargs):
print "before some_func"
ret = some_func(*args, **kwargs)
return ret + 1
return inner
def foo():
return 1
decorated = outer(foo)
decorated()
# 当调用外部函数时会返回内部函数的引用,将要装饰的函数引用作为变量传进去,再将返回的内部函数赋值给原来的函数名,
# 原函数名()实际上运行的是inner()
实际应用时通常用@装饰函数名应用到函数上,@方法本质上是语法糖,让其实现更加简洁,本质上是上面的原理。
2、迭代器:
符合以下格式的对象被称为迭代器
class Iterator(object):
def __init__(self):
pass
def __iter__(self):
"""
通过该方法取得迭代器对象
"""
return self
def __next__(self):
"""
取得下一个迭代的值,直到结尾抛出StopIteration异常
"""
pass
迭代器与可迭代对象的区别:
1、可迭代对象是实现了iter()方法的对象,iter()可以返回一个迭代器对象;
2、迭代器对象是实现了next()方法的对象,其中他的iter()返回的是迭代器对象本身;
3、迭代器本身一定是个可迭代对象。
备注:通过isinstance(对象, Iterable)方法判断一个对象是否是可迭代对象,iter(可迭代对象)可以返回该可迭代对象的迭代器,next(迭代器)返回可迭代对象的下一条数据。
3、生成器
def fib(n):
current_index = 0
num1, num2 = 0, 1
while current_index < n:
# print(num1) # 打印斐波那契数列
"""
1. 假如函数中有yield,则不再是函数,而是生成器
2. yield 会产生一个断点
3. 假如yield后面紧接着一个数据,就会把数据返回,
作为next()函数或者for ...in...迭代出的下一个值
"""
temp = yield num1
print(temp)
num1, num2 = num2, num1 + num2
current_index += 1
yield关键字有两点作用:
1、保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起;
2、将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用。
3、temp当使用 生成器对象.send(msg) 唤醒生成器时可以接受msg,next(生成器对象)的和上者都可以用来唤醒并执行生成器,不同的是send()函数的一个好处是可以在唤醒的同时向断点处传入一个附加数据。
迭代器是本质上是生成器,其实现方式更加优雅