字典、集合,文件都没有索引。
装饰器
一:开放封闭原则,对扩展是开放的,对修改是封闭的
二:装饰器,装饰器可以是任意可调用对象,被装饰的对象也可以是任意可调用对象,
三:原则:
1.不修改源代码
2.不修改调用方法
1、迭代器:
1、Zip,min ,max 都是迭代器。
2、数字不可迭代。
3、next 触发迭代器的执行。
def func(n):
while True:
yield n
n-=1
g=func(5)
print(next(g))
查看是否可迭代:
# print(hasattr(d,'__iter__')) #适合python3
For取值
for i in d:
print(i)
while取值
obj=d.__iter__()
while True:
try:
print(obj.__next__())
except StopIteration:
break
2、生成器
Yield
把__iter__和__next__方法封到函数里。
- 包含yield关键字的函数叫生成器。
- 生成器本质就是迭代器。
- 生成器的用途:模拟管道,惰性计算。
Yield的表达式形式
send
Send基于暂停的yield,给yield传一个值,再继续往下执行。表达式形式的yield,第一件事应该是初始化,让生成器走到一个暂停的位置。
写个装饰器,功能是初始化生成器。
def init(func):
def wrapper(*args,**kwargs):
x=func(*args,**kwargs)
next(x)
return x
return wrapper
@init
def eater(name):
print('%s please ready' % name)
food_list=[]
while True:
food = yield food_list
food_list.append(food)
print('please %s eat %s' %(name,food))
def make_food(people,n):
for i in range(n):
people.send('food%s' %i)
eater('alex').send('tudou')
make_food(eater('alex'),5)
应用:grep –rl ‘root’ /etc
Day22 ==》3面向过程编程
#!/usr/bin/env python
# coding:utf-8
import os
def init(func):
def wrapper(*args,**kwargs):
g=func(*args,**kwargs)
next(g)
return g
return wrapper
#阶段一:递归地找文件的绝对路径,把路径发给阶段二。
def search(target,start_path):
'search file obspath'
g = os.walk(start_path)
for par_dir,_,files in g:
#print(par_dir,files)
for file in files:
file_path = r'%s\%s' % (par_dir,file)
target.send(file_path)
#阶段二:收到文件路径,打开文件获取对象,把文件对象发给阶段三。
@init
def opener(target):
'get file obj: f=open(filepath'
while True:
file_path=yield
with open(file_path) as f:
target.send((file_path,f)) #需要以元组的形式
#阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四.
@init
def cat(target):
'read file'
while True:
filepath,f=yield
for line in f:
target.send((filepath,line))
#阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五。
@init
def grep(target,pattern):
'grep function'
while True:
filepath,line=yield
if pattern in line:
target.send(filepath)
#阶段五:
@init
def printer():
'print function'
while True:
filename=yield
print(filename)
start_path=r'd:\dddd'
search(opener(cat(grep(printer(),'root'))),start_path)
厨师做包子给吃货(yield,面向过程,)
#!/usr/bin/env python
#coding:GBK
#厨师 , count:造多少个包子
import time
import random
def init(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
next(res)
return res
return wrapper
def producer(target,count):
for i in range(count):
time.sleep(random.randrange(1,3))
print('\033[35m厨师造好的包子%s\033[0m'%i)
target.send('baozi%s' %i)
#吃货
@init
def consummer(name):
while True:
food=yield
time.sleep(random.randrange(1,3))
print('\033[36m%s start to eat %s\033[0m' %(name,food))
producer(consummer('alex'),4)
#*************************
def producer(count):
res=[]
for i in range(count):
res.append('baozi%s' %i)
return res
# print(producer(4))
def consumer(name,res):
for i in res:
print('%s吃%s'%(name,i))
consumer('alex',producer(4))
3、列表解析
print([i for i in range(10) if i>5])
s='hello' res=[i.upper() for i in s] print(res)
l=[1,31,73,84,57,22] l_new=[] for i in l: if i > 50: l_new.append(i) print(l_new)
print([i for i in l if i > 50]) #列表解析
l1=['x','y','z'] l2=[1,2,3] l3=[(a,b) for a in l1 for b in l2] print(l3)
print('\n'.join([''.join(['%s*%s=%-2s '%(y,x,x*y)for y in range(1,x+1)])for x in range(1,10)]))
4、生成器表达式(元组)
a=(i for i in range(10) if i > 5)
print(next(a))
g=(i for i in range(10000000000) ) #生成器表达式,语法和列表解析一样#得到的结果是生成器#生成器就是迭代器
print(g)
print(next(g))
print(next(g))
print(next(g))
print(g.__next__()
5、三元表达式:
格式:
Res = True if 1>2 else False
def f(x,y):
return x - y if x>y else abs(x-y) #如果x大于y就返回x-y的值 ,否则就返回x-y的绝对值
print(f(3,4))
6、拉链函数
salaries={'egon':3000, 'alex':90000000, 'wupeiqi':10000, 'yuanhao':2000} print(max(salaries)) #默认按key,z最大。 print(max(salaries.values())) #找出最大的values res=zip(salaries.values(),salaries.keys()) #拉链函数。 print(max(res)[-1])
7、列表推倒式:
#列表推导式是利用其他列表创建新列表的一种方法。
1、求总价格
1、文件a.txt内容:每一行内容分别为商品名字,价钱,个数;
要求一:使用列表解析,从文件a.txt中取出每一行,做成下述格式:[{‘name’:'apple','price':10,'count':3},{...},{...},...]
要求二:求出总共消费了多少钱(5分)
apple 10.3 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3
答案
with open(r'inspectionProfiles\0621a.txt','r') as f: l=[float(line.split()[1])*int(line.split()[2]) for line in f] # ==》由[换成(,就变成了生成器,然后由next取值,sum是自带next功能的函数。 print(sum(l)) # ==》with代码段执行完,文件就关闭。所以这个print必须在with代码段下面。
第二种方式:将数据做成字典类型,进行处理
goods_info=[]
with open(r'inspectionProfiles\0621a.txt','r') as f:
for line in f:
l = line.split()
goods_info.append({'name':l[0],'price':l[1],'count':l[2]})
print(goods_info)
2、求1到10每个数的平方
# a=[x*x for x in range(10)]
# print(a)
3、求出1到10的2次方幂中能被3整除幂。
在推导式中添加一个if就可以完成:
# b=[x*x for x in range(10) if x % 3 ==0] #for循环取值后放到左边,再if判断。
# print(b)
4、两个for循环的列表推导式
# c=[(x,y) for x in range(3) for y in range(3)] # print(c) # d=[[x,y] for x in range(2) for y in range(2)] print(d) #结果:[[0, 0], [0, 1], [1, 0], [1, 1]] e=[x*y for x in range(2) for y in range(2)] print(e) #结果:[0, 0, 0, 1] #—————————————————————————————————————— # a=(x*x for x in range(10)) #小括号中有for循环就是生成器 # print(a.__next__()) # print(a.__next__())
9、匿名函数:
#匿名函数的作用:调用一次就关闭,避免占用内存。
func=lambda x:x**2
print(func(2))
f1=lambda x,y:x+y
print(f1(2,5))
ff=lambda x:x>1
print(ff(3))