Python学习笔记Day04 - 装饰器与生成器
1.装饰器 = 高阶函数+嵌套函数
装饰器:本质是函数,用来装饰其他函数,用来添加额外的功能。
原则:1.不能修改被装饰函数的源代码
2.不能修改被装饰函数的调用方式
def deco1(func): # func = bar
def inner_func(*args, **kwargs):
print('函数bar前面添加代码')
i = func(*args, **kwargs) # 运行原函数bar
print('函数bar后面添加代码')
return i # 返回原函数的返回值
return inner_func
装饰器的四种情况
-
原函数无参数时
@deco1 # 在原函数前添加deco标记,等效于在调用时使用 bar = deco(bar) # 这一步在运行deco函数,将bar重定义 def bar1(): ...
-
原函数有参数时
@deco1 def bar2(name, age): ...
-
原函数有返回值
@deco1 def bar3(): print('in the bar3') return_bar3 = 'return in bar3' return return_bar3 bar2('zhang',18) print(bar3()) def deco(job): # 加参数,添加一层嵌套,其他不变 def deco2(func): # func = bar def inner_func(*args, **kwargs): print('----------', end='') i = func(*args, **kwargs) print(':', job, end='') print('----------') return i return inner_func return deco2
-
装饰函数加参数
@deco(job='engineer') def bar4(): print('in the bar4', end='') bar4()
装饰器原理
-
函数即变量
-
示范一:
def foo(): print('in the foo') foo()
-
示范二:bar在foo前
def bar(): print('in the bar') def foo(): print('in the foo') bar() foo()
-
示范三:bar在foo后
def foo(): print('in the foo') bar() def bar(): print('in the bar') foo()
-
示范四:定义在调用之后
def foo(): print('in the foo') bar() foo() def bar(): print('in the bar')
-
-
高阶函数
a. 把函数名当作一个参数传给另一个函数
b. 返回值中包含函数名# 不改原函数,添加新代码, 是一个简单装饰器 def bar(): print('in the bar') def test1(func): print('-----in the test1-----') return func # 返回函数名 # print(test1(bar)) # 实际上返回的是函数名所代表的内存地址 bar = test1(bar) # 将返回的函数名重新定义给bar bar()
-
嵌套函数:在一个函数体内通过def定义另一个函数
2.生成器,迭代器,可迭代对象
可迭代对象:可以用于for循环的对象, Iterable
迭代器:可以被next()函数调用并不断返回下一个值的对象,Iterator
from collections import Iterable, Iterator
print(isinstance([], Iterable))
print(isinstance((x for x in range(10)), Iterator))
生成器都是迭代器, 但list,dict,str虽然是可迭代对象, 却不是迭代器
iter([]) # 将可迭代对象转换成迭代器
生成器
使用生成器,使函数在执行大量数据的时候,可以先跳出执行命令,不影响其他操作
使用next(),当迭代结束的,抛异常
生成器:只有在调用的时候才会生成相应的数据,不能返回上一组数据,只记住当前位置
生成器只有一个__next__()方法,实际上生成器应用中__next__()方法用到较少,而是通过for来循环它
def fib(max): # 10
n, a, b = 0, 0, 1
while n < max: # n<10
yield b # 生成器在此处跳出函数,返回b
a, b = b, a + b
n = n + 1
return '---done---' # 异常的时候打印的消息
f = fib(10)
print('干点别的事')
print(f.__next__()) # 走到生成器的下一个yield处
print(f.__next__())
print('再干点别的事')
print(f.__next__())
print("====start loop======")
for i in f: # 使用for进行迭代,不抛异常,直接结束
print(i)
g = fib(6)
while True:
try:
x = next(g)
print('g:', x)
except StopIteration as e: # 抓迭代结束的异常
print('Generator return value:', e.value)
break
生成器的并行
import time
def consumer(name):
print('%s开始吃包子' % name)
while True:
index = yield
print('%s 吃了%s#包子' % (name, index))
def producer(count):
c1 = consumer('猪八戒')
c2 = consumer('孙悟空')
c1.__next__() # 取生成器的下一个数据
c2.__next__()
print('开始做包子')
for i in range(count):
time.sleep(1)
print('做了两个%d#包子' % (i+1))
c1.send(i+1)
c2.send(i+1)
return
producer(3)
# consumer('猪八戒').__next__()
# consumer('zhang').send('11')
3.内置函数
all([1, 2, 0, 3]) # 全为True
any([1, 2, 0, 3]) # 有一个True
exec(code) # 执行字符串代码
eval("1,2,3,4") # 字符串转字典
res = filter(lambda i: i > 5, range(10)) # 筛选出想要的,隐函数lambda不可写复杂语句
res = map(lambda i: i * i, range(10)) # 对值按某种方式进行处理 = [i*i, for i in range(10)]
import functools
res = functools.reduce(lambda x, y: x + y, range(1, 10)) # 逐个取值进行运算,累加
a = frozenset([1, 4, 333, 212, 33, 33, 12, 4]) # 冻结,使集合不可变,相当于元组
print(globals()) # 返回当前程序的所有的变量,以键值对形式表示
pow(2, 3) # 幂函数
round(1.3231, 3) # 控制小数位数
a = {1: 3, 2: 2, 3: 1}
sorted(a) # [1,2,3] 默认将key排序输出
sorted(a.items()) # 字典按key排序,生成的是以每组键值对为tuple的list=[(1, 3), (2, 2), (3, 1)]
sorted(a.items(), key=lambda x: x[1]) # 字典按value排序,x相当于每个tuple
a = [1, 2, 3, 4, 5, 6]
b = ['a', 'b', 'c', 'd']
for i in zip(a, b): # 拉链 将a,b中的相应项一一对应起来,以tuple输出:(1, 'a')
print(i)
# import iterator
__import__('_iterator') # 引用字符串名的模块