Python全栈之路Day22,,初次编辑2017年1
Python全栈之路Day22,,初次编辑2017年1
初次编辑2017年10月28日,星期六
一. 上节课复习
二. 协程函数初始化装饰器
三. send实现爬网页
四. 面向过程的程序设计
五. 列表生成式
六. 三元表达式
七.生成器表达式
八. 声明式编程
作业
今日总结
摘要
引用:百度
列表生成式生成器表达式面向过程编程递归一. 上节课复习
可迭代的:对象有__iter__方法的都是可迭代的对象迭代器:对象 .iter()得到的结果就是迭代器迭代器的特征:迭代器.next()取下一个值优点:提供了一种统一的迭代对象的方式,不依赖于索引惰性计算缺点:无法获取迭代器的长度一次性的,只能往后取值,不能往前退,不能像索引那样去取得某个位置的值生成器:函数带有yield关键字,那么这个函数的执行结果就是生成器生成器的本质就是迭代器def func(): n=0 while True: yield n n += 1g=func()res=next(g)for i in g: pass总结yield功能:相当于把__iter__和__next__方法封装到函数内部与return相比,return只能返回一次,而yield可以返回多次函数暂停以及继续运行的状态是通过yield保存的yield的表达式形式:
food= yield
def eater(name): print(‘%s start to eat ‘%name) while True: food=yield print(‘%s eat %s‘%(name,food))e=eater(‘zhejiangF4‘)e.send与next(e)的区别如果函数内yield是表达式形式,那么必须先next(e)二者的共同之处都是可以让函数在上次暂停的位置继续运行,不一样的地方在于send在触发下一次代码的执行时,会顺便给yield传一个值另 e.send(None) 和next(e) 效果一样
二. 协程函数初始化装饰器
简单装饰器def foo(func): def foo1(*args,**kwargs): res = func(*args,**kwargs) next(res) return res #此处理解 生成器是一次性的 return foo1@foo #eater = foo(eater) = foo1def eater(name): print(‘%s start to eat food ‘% name) food_list = [] while True: food = yield food_list print(‘%s get %s, to start eat ‘% (name, food)) food_list.append(food) print(‘Done‘)e = eater(‘钢蛋‘) #foo1(‘钢蛋‘)print(e.send(‘123‘))
三. send实现爬网页
from urllib.request import urlopendef my_next(func): def foo(*args,**kwargs): res = func(*args,**kwargs) next(res) return res return foo@my_nextdef get(): while True: url = yield res = urlopen(url).read() #爬网页返回值 print(res) #输出爬网页结果g=get()g.send(‘http://www.baidu.com‘)g.send(‘http://www.python.org‘)
四. 面向过程的程序设计
面向过程的编程思想:流水线式的编程思想,在程序设计时,需要把整个流程设计出来优点:体系结构更加清晰简化程序的复杂度缺点:可扩展性极其差,所以说面向过程的应用场景是:不需要经常变化的软件实现 #grep -rl ‘python‘ C:\egon# grep -rl ‘python‘ C:\egonimport os#装饰器,将生成器next初始化def init(func): def foo(*args,**kwargs): res = func(*args,**kwargs) next(res) return res return foo@initdef search(target): ‘查找文件绝对路径‘ while True: dir_path = yield #此yield放在while外还是内有疑问:yield放在while外就会造成死循环,无法进行下次yield g = os.walk(dir_path) #g为迭代器 for i in g: # print(i) for j in i[-1]: file_path = ‘%s\\%s‘%(i[0],j) target.send(file_path)@initdef opener(target): ‘打开文件获取文件句柄‘ while True: file_path = yield with open(file_path) as f: target.send((f,file_path)) #send传递两个文件时,需加括号@initdef cat(target): ‘读取文件内容‘ while True: f,file_path = yield for line in f: #读取一行文件 target.send((line,file_path))@initdef grep(target,pattern): #传递两个参数,其中pattern为要过滤的字符串 ‘过滤文件一行中是否有python‘ while True: line,file_path = yield if pattern in line: target.send(file_path) #需传递文件路径@initdef printer(): ‘打印文件路径‘ while True: file_path = yield print(file_path)g=search(opener(cat(grep(printer(),‘python‘))))g.send(‘C:\\egon‘)
五. 列表生成式
普通表达egg_list = []for i in range(100): egg_list.append(‘egg%s‘% i)print(egg_list)列表生成式表达普通
egg_list = [‘egg%s‘%i for i in range(100)]print(egg_list)列表生成式表达if判断
#列表内只会添加大于50的数字egg_list = [‘egg%s‘%i for i in range(100) if i >50]print(egg_list)语法
[expression for item1 in interable if condition1 for item2 in interable if condition2 … for itemN in interable if conditionN ]
类似于
res = []for item1 in interable: if condition1: for item2 in interable: if condition2: … for itemN in interable: if conditionN: res.append(expression )实现查找文件绝对路径,以列表的形式表达
import osg = os.walk(‘C:\\egon‘)l = [‘%s\\%s‘% (i[0],j) for i in g for j in i[-1]]print(l)#[‘C:\\egon\\a.txt - 副本.txt‘, ‘C:\\egon\\a.txt.txt‘, ‘C:\\egon\\a\\a.txt.txt‘, ‘C:\\egon\\a\\a2.txt.txt‘, ‘C:\\egon\\b\\a.txt.txt‘, ‘C:\\egon\\b\\a1.txt.txt‘]
六. 三元表达式
name = ‘alex‘name = ‘egon‘res = ‘sb‘ if name ==‘alex‘ else ‘shuai‘print(res) #输出shuai
七.生成器表达式
语法:与列表生成式相似(expression for item1 in interable if condition1 for item2 in interable if condition2 … for itemN in interable if conditionN )优点:省内存,一次只产生一个值在内存中应用:读取一个大文件的所有内容,并且行处理
#读取文件,并去掉每一行两头空格f = open(‘a.txt‘)g= (line.strip() for line in f)print(next(g))
注意:因g为可迭代的,因而可以转换成列表list(g)
八. 声明式编程
消费总额计算#鸡蛋 5 3#特斯拉 10000000.2 5#上衣 1000 3#裤子 2000 3#袜子 100#读取包含以上信息的文件,并计算总共花费#第一种传统写法total = []with open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) as f: for line in f: goods=line.split() #split用法及返回值需加强 # print(goods) res = float(goods[1])*float(goods[-1]) total.append(res)print(total)print(sum(total))#第二种声明式编程写法f=open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) #不能用with 否则会IO操作报错total=(float(line.split()[1])*float(line.split()[-1]) for line in f)print(total)print(sum(total))文件内容以字典形式嵌套在列表中
#[{‘name‘: ‘袜子‘, ‘price‘: ‘100‘, ‘num‘: ‘3‘}, {‘name‘: ‘袜子‘, ‘price‘: ‘100‘, ‘num‘: ‘3‘}, {‘name‘: ‘袜子‘, ‘price‘: ‘100‘, ‘num‘: ‘3‘}, {‘name‘: ‘袜子‘, ‘price‘: ‘100‘, ‘num‘: ‘3‘}, {‘name‘: ‘袜子‘, ‘price‘: ‘100‘, ‘num‘: ‘3‘}]# 基本写法res = []d = {}with open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) as f: for line in f: l = line.split() d[‘name‘] = l[0] d[‘price‘] = l[1] d[‘num‘] = l[2] res.append(d)print(res)模拟数据库查询
with open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) as f: res = (line.split() for line in f) dic_g = ({‘name‘:line[0],‘price‘:line[1],‘num‘:line[2]} for line in res) goods_dic = next(dic_g) print(goods_dic[‘num‘])关于with open() 报错
with open(‘b.txt‘) as f: d = fprint(d) #有内存地址,不是很理解print(next(d)) #报错
作业
今日总结
Python全栈之路Day22
评论关闭