一、生成器
只有当需要使用值时,才生成数据,避免了没有内存储存庞大的数据问题。
1、创建生成器
①创建生成器方法1
#1、把列表生成器的中括号编程小括号
a = [x for x in range(10)]
#[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
b = (x for x in range(10))
#b为生成器
#输出b
for i in range(10):
next(b)
②创建生成器方法2
#生成斐波那契数列方法
def creatNum():
a, b = 0, 1
for i in range(5):
yield b
a, b = b, a+b
num = creatNum() #生成器
#next(num)
#num.__next__()
#以上两种方式是一样的
for n in num:
print(n)
#num 这个生成器执行,如果是第一次执行,则从creatNum开始执行;否则,从上次停止的地方执行。
#每次函数执行都会在yield处停止,并返回一个值
2、send
def test():
for i in range(5):
temp = yield(i)
print(temp)
t = test()
print(next(t))
print(next(t))
# 0
# None
# 1
print(t.send('haha'))
# haha
#2
# yield 没有返回值 None
# send 给yield传递信息,从yiel停止处执行,故不能直接第一次就执行send
# 若非要第一次就执行 send ,则可 t.send(None)
二、迭代器
1、可迭代对象:Iterable
①集合类型数据:list、tuple、dict、set、str等
②generator,包括生成器和带 yield 的 generator function
如何判断一个对象是否可迭代:
from collections import Iterable
#用 isinstance 判断
isinstance([], Iterable) #True
#True表示可以迭代,False表示不可迭代
2、迭代器
可以被next() 函数调用,不断返回下一个值的对象称为迭代器:Iterator
from collections import Iterator
#用 isinstance 判断
isinstance([], Iterator) #False
#True表示可以迭代,False表示不可迭代
3、iter()函数
生成器都是Iterator对象,但list、dict、str虽然可以iterable但那不是iterator,用iter函数可以使他们变成迭代器
isinstance(iter([]), Iterator) #True
三、闭包
1、函数引用
def test():
for i in range(5):
print("-------1-----")
b = test # b 为函数引用
2、闭包
在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的变量称为闭包
def test(number):
print("-------1-------")
def test_in():
print("-------2-------")
print(number+100)
print("-------3-------")
return test_in
t = test(100)
print("---------------------")
t()
# 输出为:
# -------1-------
# -------3-------
# ---------------------
# -------2-------
# 200
闭包的实例
#创建直线方程
def line_conf(a, b):
def line(x):
return a*x + b
return line
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line(5))
print(line(5))
四、装饰器
在不改变原有函数功能的情况下,对函数进行扩展。
def w1(func):
def inner():
print("----正在验证权限----") #扩展部分
func()
return inner
def f1():
print("-----f1-----")
def f2():
print("-----f2-----")
#在不改变 原f1 函数的基础上,对 f1 进行功能上的扩展
f1 = w1(f1)
f1()
def w1(func):
def inner():
#验证1
#验证2
#验证3
func()
return inner
@w1
def f1():
print("f1")
@w1
def f2():
print("f2")
@w1
def f3():
print("f3")
@w1
def f4():
print("f4")
装饰器什么时候开始起作用:
def w1(func):
print("----正在装饰中-----")
def inner():
print("----正在验证权限----") #扩展部分
func()
return inner
#只要python解释器执行到了这行代码,那么就会自动进行装饰,而不是等到调用的时候才进行装饰
@w1
def f1():
print("-----f1-----")
#在调用f1之前,已经进行了装饰
f1()
# @w1 就相当于 f1 = w1(f1)
1、装饰器对有参数、无参数函数进行装饰
对无参数的函数进行装饰
def func(funcName):
print("--func-1----")
def func_in():
print("---func_in-1--")
funcName()
print("---func_in-2--")
print("--func-2----")
return func_in
@func
def test():
print("----test-----")
test()
对有参数的函数进行装饰
#对定长参数函数进行装饰
def func(funcName):
print("--func-1----")
def func_in(a, b):
print("---func_in-1--")
funcName(a, b)
print("---func_in-2--")
print("--func-2----")
return func_in
@func
def test(a, b):
print("----test-----")
test(11, 22)
#对不定长参数函数进行装饰
def func(funcName):
print("--func-1----")
def func_in(*args, **kwargs):
print("---func_in-1--")
funcName(*args, **kwargs)
print("---func_in-2--")
print("--func-2----")
return func_in
@func
def test1(a, b):
print("a=%d,b=%d"%(a,b))
@func
def test2(a, b, c):
print("a=%d,b=%d,c=%d"%(a,b,c))
test1(11, 22)
test2(11, 22, 33)
2、对带有返回值的函数进行装饰
#对定长参数函数进行装饰
def func(funcName):
print("--func-1----")
def func_in():
print("---func_in-1--")
ret = funcName() #保存返回的"haha"
print("---func_in-2--")
return ret
print("--func-2----")
return func_in
@func
def test(a, b):
print("----test-----")
return "haha"
ret = test()
print("test return value is %s"%ret)
3、通用装饰器
def func(funcName):
def func_in(*args, **kwargs):
ret = funcName(*args, **kwargs)
return ret
return func_in
@func
def test1():
print("----test1----")
return "haha"
@func
def test2():
print("----test2----")
@func
def test3(a):
print("----test3----a=%d"%a)
ret = test1()
print("test1 return value is %s"%ret)
test2()
test3(11)
4、带有参数的装饰器
装饰器带参数,在原有装饰器的基础上,设置外部变量
def func_arg(arg):
def func(funcName):
def func_in():
print("-----args=%s----"%arg)
funcName()
return func_in
return func
# 1、先执行func_arg("heihei")函数,这个函数return的结果是func这个函数的引用
# 2、@func
# 3、使用 @func 对函数test进行装饰
@func_arg("heihei")
def test1():
print("----test1----")
@func_arg("haha")
def test2():
print("----test2----")
#带有参数的装饰器,能够在运行时,有不同的功能
test1()
test1()
5、类当装饰器
class Test(object):
def __init__(self, func):
print("----初始化----")
print("func name is %s"%func.__name__)
self.__func = func
def __call__(self):
print("----装饰器中的功能----")
self.__func()
# @Test 等同于 test = Test(test)
@Test
def test():
print("----test----")
#装饰器 @Test 处执行__init__
#----初始化----
#func name is test
test() #执行 __call__
#----装饰器中的功能----
#----test----