4)装饰器迭代器生成器以及内置函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4)装饰器迭代器生成器以及内置函数相关的知识,希望对你有一定的参考价值。
装饰器、迭代器、生成器以及内置函数
装饰器:
原函数前后增加功能,切不改变函数的原本使用方式
import time
def wrapper(f):
def inner():
start = time.time()
f()
end = time.time()
print('执行效率为%s'%(end-start))
return inner
@wrapper
def func():
print('this is func')
time.sleep(0.3)
func()
import time
def wrapper(f):
def inner(*args,**kwargs):#带参数的装饰器
start = time.time()
f(*args,**kwargs)
end = time.time()
print('执行效率为%s'%(end-start))
return inner
@wrapper
def func(a,b):
print(a,b)
print('this is func')
time.sleep(0.3)
func(111,222)
再加一个666
import time
def wrapper(f):
def inner(*args,**kwargs):#带参数的装饰器
start = time.time()
set = f(*args,**kwargs)
end = time.time()
print('执行效率为%s'%(end-start))
return set
return inner
@wrapper
def func(a,b):
print(a,b)
print('this is func')
time.sleep(0.3)
return 666
print(func(111,222))
进阶需求:
情况一:
500个函数
设计装饰器,确认是否生效
import time
FLAG = True
def outer(flag):
def wrapper(f):
def inner(*args,**kwargs):#带参数的装饰器
if flag == True:
start = time.time()
set = f(*args,**kwargs)
end = time.time()
print('执行效率为%s'%(end-start))
else:
set = f(*args,**kwargs)
return set
return inner
return wrapper
@outer(FLAG)
def func(a,b):
print(a,b)
print('this is func')
time.sleep(0.3)
return 666
print(func(111,222))
情况二:
登陆,纪录日志
login_info = {'alex':False}
def login(func):
def inner(name):
if login_info[name] !=True:
user = input('>>>user')
pwd = input('>>pwd')
if user =='alex' and pwd =='alex3714':
login_info[name] = True
if login_info[name] == True:
ret = func(name)
return ret
return inner
def wrapper1(func): #f
def inner1():
print('wrapper1 ,before func')
func() # f
print('wrapper1 ,after func')
return inner1
def wrapper2(func): # inner1
def inner2():
print('wrapper2 ,before func')
func() # inner1
print('wrapper2 ,after func')
return inner2
@wrapper2
@wrapper1
def f():
print('in f')
f()
import time
login_info = {'alex':False}
def login(func):
def inner(name):
if login_info[name] !=True:
user = input('>>>user')
pwd = input('>>pwd')
if user =='alex' and pwd =='alex3714':
login_info[name] = True
if login_info[name] == True:
ret = func(name)
return ret
return inner
def timmer(f):
def inner(*args,**kwargs):
start = time.time()
ret = f(*args,**kwargs)
end = time.time()
print('执行效率%s'%(end-start))
return ret
return inner
@login
@timmer
def index(name):
print('欢迎%s考到博客园'%name)
time.sleep(0.3)
@login
@timmer
def manager(name):
print('欢迎%s考到博客园管理页面'%name)
time.sleep(0.3)
index('alex')
manager('alex')
迭代器和生成器
迭代器:
凡是可以使用for循环取值的都是可迭代的
#从列表、字典中取值
# index索引
#for 凡是通过for循环取值的都是可迭代的
可迭代协议:
内部有__iter__方法的都是可迭代的
迭代器协议:
内部有__iter__和__next__方法的都是迭代器
创建迭代器使用__iter__() 或者 iter()
dir()可以查看使用的内置方法
l = [1,2,3]
ll = iter(l)
print(ll.__next__())
print(ll.__next__())
l = [1,2,3]
lst_iter = iter(l) #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()
while True:
print(next(lst_iter)) #lst_iter.__next__()
l = [1,2,3]
ll = iter(l)
while True:
print(next(ll)) #报错了
没有就会出错
l = [1,2,3]
lst_iter = iter(l) #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()
while True:
try:
print(next(lst_iter)) #lst_iter.__next__()
except StopIteration:
break
总结:
什么是可迭代:内部有__iter__
什么是迭代器:迭代器=iter(可迭代的) 自带__next__方法
节省内存
Range()
from collections import Iterable,Iterator
print(range(10000))
print(isinstance(range(10000),Iterable)) #True
print(isinstance(repr(10000),Iterator)) #False
Python2的range会生成一个列表,将用来存储生成所有的值
Python3,range不管要多少,都不会生成实际的值
在使用的时候在生成
for i in range(1000):
节省内存,速度快
特性:惰性运算
生成器:
自己写的迭代器就是生成器
两种自己写生成器的机制:
生成器函数:
凡是带有yield的函数是个生成器
def func():
print('****')
yield 1
g = func()
next(g)
def func():
print('****')
yield 1
print('^^^^')
yield 2
g = func()
print('___',next(g))
print('===',next(g))
Yield 记录当前所在位置,等待下一次next来触发函数的状态
想要执行要next
def cloth_g(name):
for i in range(name):
yield 'choth_g%s'%i
g = cloth_g(10)
next(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
使用生成器监听文件输入:
import time
def lister_file():
with open('userinfo') as f1:
while True:
line = f1.readline()
if line.strip():
yield line.strip()
time.sleep(0.3)
g = lister_file()
for i in g:
print(i)
if i =='error':
break
Send 关键字
在执行next的时候,传递一个参数给生成器函数的内部
1)
def func():
print(1111)
yield 1
print(2222)
yield 2
print(3333)
yield 3
func()
next(func())
next(func())
2) :
def func():
print(1111)
yield 1
print(2222)
yield 2
print(3333)
yield 3
g = func()
ret = next(g)
print(ret)
3) :
def func():
print(1111)
ret1 = yield 1
print(2222,'ret1:',ret1)
ret2 = yield 2
print(3333,'ret2:',ret2)
yield 3
g = func()
ret = next(g)
print(g.send('alex'))
print(g.send('lxf'))
向生成器中传递值,有个激活过程,第一次必须用next触发这个生成器
def average():
sum_money = 0 #总钱数
day = 0 #天数
avg = 0 #平均的钱
while True:
money = yield avg
sum_money += money
day +=1
avg = sum_money/day
g = average()
next(g)
print(g.send(200))
print(g.send(300))
例子:
预激生成器:
就是吧要激活的next放到一个装饰器当中,比如说有多个程序需要激活的话,可以这样做,为了简便,如果要是就一个程序的话就没有必要了
yield from:
def generator_func():
for i in range(5):
yield i
for j in 'hello':
yield j
g = generator_func()
#如何取值
#1,next、随时可以停止,最后会报错
print(next(g))
print(next(g))
#2,for循环、从头到尾遍历一次,不遇到break、return不停止
for i in g:
print(i)
#3,list、tuple
print(list(g))#一次性所有的都转换了,如果多太占内存
print(g)
上面的内容可以进行替换成如下:
def generator_func():
yield from range(5)
yield from 'hello'
# for i in range(5):
# yield i
# for j in 'hello':
# yield j
g = generator_func()
for i in g:
print(i)
总结:
1)生辰器函数,是我们python程序员实现迭代器的一种手段
2)主要特征是在函数中含有yield
3)调用一个生成器函数,不会执行这个函数中的代码,只是会获得一个生成器代码
4)只有从生辰器中取值的时候,才会执行函数内部的代码,且每获取一个数据才执行的到这个数据的代码
5)获取数据方式,next、send 循环 数据类型的强制转化
6)Yield 返回值的简便方法,如果本身就是循环一个可迭代,且要把可迭代数据中的每一个元素都返回,可以用yield from
7)使用send的时候,在生成器创造出来之后需要进行预激活,这一步可以使用装饰器完成
8)生成器特点:节省内存、惰性运算
9)生成器用来解决内存和程序功能之间的解耦
列表推到试:表现为 []
new = []
for i in range(10):
new.append(i**2)
print(new)
#上面的复杂不好
print([i **2 for i in range(10)])#列表推到式
ll = [1,2,3,-5,6,20,-7]#求每个数的余数
print([ i%2 for i in ll])
ll = [1,2,3,-5,6,20,-7]
print([i for i in ll if i %2 ==0])
#30以内搜友能被3整除的数
print([i for i in range(30) if i % 3 ==0])
#30以内搜友能被3整除的数的平方
print([i**2 for i in range(30) if i % 3 ==0])
#:找到嵌套列表中名字含有两个‘e’的所有名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# for i in names:
# for j in i: #复杂不好
# if j.count('e') ==2:
# print(j)
print( [j for i in names for j in i if j.count('e') ==2])
生成器表达式:表现为 ()
练习题:
自定义函数:
自己定义的【name = ‘uuu’】
内置函数:
拿过来直接用的,python直接封装好的
Print、len、max、min、dir
迭代器/生成器相关的:
Range、next 、iter
作用域相关的:
Globals
Locals
其他:
Input:
Print:九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print('%s*%s=%2s'%(i,j,i*j),end=' ')
print()
print(1,2,3,4,5,sep=';',end=' ')#1;2;3;4;5
print(1,2,3,4,5,sep=';',end='')#1;2;3;4;5
进度条
import time
for i in range(0,101,2):
time.sleep(0.1)
char_num = i//2
per_str = '\r%s%% : %s\n' % (i, '*' * char_num) if i ==100 else'\r%s%% : %s'%(i,'*'*char_num)
print(per_str,end='')
import time
for i in range(0,101,2):
time.sleep(0.1)
char_num = i//2
if i ==100:
per_str = '\r%s%% : %s\n' %(i,'*'* char_num)
else:
per_str='\r%s%%: %s'%(i,'*' *char_num)
print(per_str,end='')
Hash:
对可hash的数据类型进行hash之后会的到一个数字
在一次程序的执行过程中,对相同的可哈希变量,哈希之后的结果永远相同
在一次程序的执行过程中,对不相同的可哈希变量,哈希之后的结果几乎是不相同的
hash字典底层的存储和set 集合的去重机制都有关
Id():
Open:
Import:
Help:
Callable:可调用
def func():
pass
a = 1
print(callable(func))#True
print(callable(a))#False
Dir: 查看这一个变量的所有方法、属性
Bin:进制
:
print(bin(10))#二进制
print(oct(10))#十进制
print(hex(10))#十六进制
abs计算数字绝对值
print(abs(4))
print(abs(-4))
divmod:商余函数
print(divmod(10,2))#(5, 0)
print(divmod(7,3))#(2, 1)
print(divmod(9,7))#(1, 2)
Round:小数精确
print(round(3.1415926,4))#3.1416 小数精确四舍五入
Pow:平方
print(pow(2,3))#8
print(pow(3,2))#9
Sum:求和
print(sum([1,2,3,4,5]))
Min:计算最小值
print(min([1,2,3,4,5]))#1
print(min([1,2,3,4,5]))#1
print(min(1,-2,3,-4,key=abs))#1
def func(num):
return num%2
print(min(-2,3,-4,key=func))
Max:和min一样
List
Tuper
Reverse:反转
Reversed()
ret = [1,2,3,4,5]
ret1 = reversed(ret)
ret2 = reversed((1,2,3,4,5))
print(ret)#[1, 2, 3, 4, 5]
print(list(ret1))#[5, 4, 3, 2, 1]
print(list(ret2))#[5, 4, 3, 2, 1]
Str
Format
Bytes
Ord
print(ord('a'))#小写的a-z 97+26 大写的A-Z 65+26
Chr
print(chr(97))#a
Repr:
print(repr(1))#1
print(repr('1'))#'1'
Enumerate:枚举函数
l = ['苹果','香蕉','橘子']
for index,i in enumerate(l,1):
print(index,i)
l = ['苹果','香蕉','橘子']
ret = enumerate(l,1)
for i in ret:
print(i[0],i[1])
没啥用:
Zip:拉链方法:
ss =zip([1,2,3,4],('a','b','c','d'))
for i in ss:
print(i)
Filter:用于过滤不需要的元素
ll = [1,4,6,7,12,17]
def func(num):
if num %2 ==0:return True
for i in filter(func,ll):
print(i)
g=(i for i in ll if i%2 ==0)
l = ['test',None,'','str', ' ','END']
def func(item):
if item and item.strip():return True
for i in filter(func,l):
print(i)
Map:
def func(num):
return num**2
for i in map(func,range(10)):print(i)
Sorted:排序功能
l = [1,-4,-2,3,-5,6,5]
l.sort(key=abs)
print(l)
l = [1,-4,-2,3,-5,6,5]
new = sorted(l,reverse=True)
print(new)
l = [[1,2,],[3,4,5,6],(7,),'123']
print(sorted(l,key=len))
eval:
eval('print(123)')
exec:
exec ('print(123)')#123
eval('print(123)')#123
print(eval('1+2-3*20/(2+3)')) -9.0
print(exec('1+2-3*20/(2+3)'))# none
匿名函数:
Lambda表达式:
逻辑比较简单
1):
add = lambda a,b: a+b
print(add(1,2))
2):
def func(num):
return num**2
for i in map(func,range(10)):print(i)
for i in map(lambda num : num**2,range(10)):print(i)
3):
def func(num):
return num%2
print(max(-2,3,-4,key=func))
print(max(-2,3,-4,key=lambda num:num%2))
递归:
递归自己调用自己
需要有一个停止的条件
以上是关于4)装饰器迭代器生成器以及内置函数的主要内容,如果未能解决你的问题,请参考以下文章
day5--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数
函数嵌套 ,名称空间与作用域 ,闭包函数 ,装饰器 ,迭代器, 生成器 三元表达式,列表解析,生成器表达式 递归与二分法, 内置函数
第四天 内置函数2 随机码 装饰器 迭代器生成器 递归 冒泡算法 JSON
装饰器 生成器 生成并运行 斐波那契 迭代器 内置函数 json and pickle
python学习第四天,列表生产式,匿名函数,生成器,内置函数,迭代器,装饰器,json和pickle的序列化和反序列化