协程函数
面向过程编程
递归和二分法
模块和包的使用
常用模块
开发代码规范
协程函数
yield:
1:把函数的执行结果封装好__iter__和__next__,即得到一个迭代器
2:与return功能类似,都可以返回值,但不同的是,return只能
返回一次值,而yield可以返回多次值
3:函数暂停与再继续运行的状态是有yield保存
yield的表达式形式的应用 x=yield
第一阶段:初始化
第二阶段:给yield传值
def func(count): print('start') while True: yield count count+=1 g=func(10) print(g) print(next(g)) print(next(g)) ''' <generator object func at 0x00000000027B1048> start 10 11 ''' # yield的表达式形式的应用 #用法: def eater(name): print('%s 说:我开动啦' %name) food_list=[] while True: food=yield food_list food_list.append(food) #['骨头','菜汤'] print('%s eat %s' %(name,food)) alex_g=eater('alex') #第一阶段:初始化 next(alex_g) #等同于alex_g.send(None) print('===========>') #第二阶段:给yield传值 print(alex_g.send('骨头')) #1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值 print('===========>') print(alex_g.send('菜汤')) print(alex_g.send('狗肉包子')) ''' alex 说:我开动啦 ===========> alex eat 骨头 ['骨头'] ===========> alex eat 菜汤 ['骨头', '菜汤'] alex eat 狗肉包子 ['骨头', '菜汤', '狗肉包子'] ''' def eater(name): print('%s 说:我开动啦' %name) food_list=[] while True: food=yield food_list food_list.append(food) #['骨头','菜汤'] print('%s eat %s' %(name,food)) def producer(): alex_g=eater('alex') #第一阶段:初始化 next(alex_g) #第二阶段:给yield传值 while True: food=input('>>: ').strip() if not food:continue print(alex_g.send(food)) producer() ''' alex 说:我开动啦 >>: 骨头 alex eat 骨头 ['骨头'] >>: 包子 alex eat 包子 ['骨头', '包子'] ''' #解决初始化问题 使用装饰器 def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def eater(name): print('%s 说:我开动啦' %name) food_list=[] while True: food=yield food_list food_list.append(food) #['骨头','菜汤'] print('%s eat %s' %(name,food)) alex_g=eater('alex') # 第二阶段:给yield传值 print(alex_g.send('骨头')) #1 先给当前暂停位置的yield传骨头 2 继续往下执行,直到再次碰到yield,然后暂停并且把yield后的返回值当做本次调用的返回值 print('===========>')
面向过程编程
面向过程:核心是过程二字,过程即解决问题的步骤,基于面向过程去设计程序就像是在设计
一条工业流水线,是一种机械式的思维方式
优点:程序结构清晰,可以把复杂的问题简单化,流程化
缺点:可扩展性差,一条流线只是用来解决一个问题
应用场景:linux内核,git,httpd,shell脚本
#grep -rl 'error' /dir/ import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper #第一阶段:找到所有文件的绝对路径 @init def search(target): while True: filepath=yield g=os.walk(filepath) for pardir,_,files in g: for file in files: abspath=r'%s\%s' %(pardir,file) target.send(abspath) # search(r'C:UsersAdministratorPycharmProjectspython18期周末班day5aaa') # g=search() # g.send(r'C:Python27') #第二阶段:打开文件 @init def opener(target): while True: abspath=yield with open(abspath,'rb') as f: target.send((abspath,f)) #第三阶段:循环读出每一行内容 @init def cat(target): while True: abspath,f=yield #(abspath,f) for line in f: res=target.send((abspath,line)) if res:break #第四阶段:过滤 @init def grep(pattern,target): tag=False while True: abspath,line=yield tag tag=False if pattern in line: target.send(abspath) tag=True #第五阶段:打印该行属于的文件名 @init def printer(): while True: abspath=yield print(abspath) g = search(opener(cat(grep('os'.encode('utf-8'), printer())))) # g.send(r'C:UsersAdministratorPycharmProjectspython18期周末班day5aaa') g.send(r'C:UsersAdministratorPycharmProjectspython18期周末班') #a1.txt,a2.txt,b1.txt
递归和二分法
递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身
递归的执行分为两个阶段:
1 递推
2 回溯
#直接 def func(): print('from func') func() func() #间接 def foo(): print('from foo') bar() def bar(): print('from bar') foo() foo() age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=18 age(n)=age(n-1)+2 #n>1 age(1)=18 #n=1 def age(n): if n == 1: return 18 return age(n-1)+2 print(age(5)) l =[1, 2, [3, [4, 5, 6, [7, 8, [9, 10, [11, 12, 13, [14, 15,[16,[17,]],19]]]]]]] def search(l): for item in l: if type(item) is list: search(item) else: print(item) search(l) #二分法 l = [1,2,5,7,10,31,44,47,56,99,102,130,240]# def binary_search(l,num): print(l) #[10, 31] if len(l) > 1: mid_index=len(l)//2 #1 if num > l[mid_index]: #in the right l=l[mid_index:] #l=[31] binary_search(l,num) elif num < l[mid_index]: #in the left l=l[:mid_index] binary_search(l,num) else: print('find it') else: if l[0] == num: print('find it') else: print('not exist') return binary_search(l,32)
模块和包的使用
模块的使用
导入模块干了哪些事:
1 执行源文件
2 以一个源文件的全局名称空间
3 在当前位置拿到一个模块名,指向2创建的名称空间
模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果
from .. import ..
优点:使用源文件内的名字时无需加前缀,使用方便
缺点:容易与当前文件的名称空间内的名字混淆
from spam import * (导入spam模块所有功能) 不推荐此*用法
了解:from spam import * *不包括下划线开头的_monney._monney只限制*
spam模块中__all__=['money','x'] 限制*只能拿到下划线__all__里的内容。__all__只限制*。
略重要:python优化机制,python模块只在第一次导入才会执行,之后的导入都是直接饮用内存已经加载存在的结果。
import sys
print(sys.modules) 存放的是已经加载到内存的模块
print('spam' in sys.modules)
模块中内容更改后,重新加载模块功能方法:(模块更改,重新启动程序)
import importlib
importlib.reload(spam)
结论:
注意:自定义的模块名一定不要与python自带的模块名重名
内存中模块--》内置模块————》硬盘sys.path下模块
sys.path增加路径方法:
import sys
sys.path.insert(0,r'C:UsersAdministratorPycharmProjectspython18期周末班day5模块模块的搜索路径aaa')
如何区分python文件的两种用途:文件脚本执行,文件模块引用。
文件当做脚本运行时__name__等于__main__
文件当做模块被加载运行时__name__等于模块名
if __name__=='__main__':当做脚本执行
pyc文件:cmd下可以dir查看当下的所有文件
print('from the spam.py') __all__=['money','x'] #对from spam import * 有用 # _money=1000 #对from spam import * 有用 money=0 x=1 def read1(): print('spam->read1->money',money) def read2(): print('spam->read2 calling read') read1() def change(): global money money=0
import spam money=100000000000 def read1(): print('from test') print(spam.money) print(spam.read1) spam.read1() spam.read2() spam.change() print(money) spam.read1() ''' from the spam.py 0 <function read1 at 0x00000000025AA8C8> spam->read1->money 0 spam->read2 calling read spam->read1->money 0 100000000000 spam->read1->money 0 ''' import spam as s1 print(s1.money) sql_type=input('sql_type: ') if sql_type == 'mysql': import mysql as sql elif sql_type == 'oracle': import oracle as sql sql.sqlparse() #mysql.py def sqlparse(): print('mysql sqlparse') #oracle.py def sqlparse(): print('orale sqlparse') import sys print(sys) import spam print(spam) # 模块只在第一次导入时才会执行,之后的导入都是直接引用内存已经存在的结果 import sys print('spam' in sys.modules) #存放的是已经加载到内的模块 import spam print('spam' in sys.modules) import spam # import spam # import spam # import spam # import spam # 优点:使用源文件内的名字时无需加前缀,使用方便 # 缺点:容易与当前文件的名称空间内的名字混淆 from spam import money,read1,read2,change money=0 print(money) print(read1) read1() def read1():print('ok') read2() money=10 change() print(money) from spam import money as m print(m) from spam import * print(_money) read1() print(read2) print(money) print(x) print(read1)
View Code
包的使用
sys.path.append(r'C:UsersAdministratorPycharmProjectspython18期周末班day5a')
#__init__.py文件下需要有get、create_resource模块方法
import m1 #报错
from aaa import m1 #C:UsersAdministratorPycharmProjectspython18期周末班day5包
from aaa import bbb
from aaa.m1 import func1
from aaa.m2 import func2
from aaa.bbb.m3 import func3
import sys print(sys.path) sys.path.append(r'C:UsersAdministratorPycharmProjectspython18期周末班day5a') import aaa
print(aaa)
print(aaa.x) #AttributeError: module 'aaa' has no attribute 'x'
import sys
sys.path.append(r'C:UsersAdministratorPycharmProjectspython18期周末班day5a')
import glance_v1
#在aaa包的__init__.py文件下需要有get、create_resource模块
glance_v1.get()
glance_v1.create_resource('test.conf')
glance_v1.main()
glance_v1.register_models('mysql')
#__init__.py文件下需要有get、create_resource模块方法
import m1 #报错
from aaa import m1 #C:UsersAdministratorPycharmProjectspython18期周末班day5包
from aaa import bbb
from aaa.m1 import func1
from aaa.m2 import func2
from aaa.bbb.m3 import func3
常用模块
软件开发代码规范
目的:维护起来方便
目录结构如下:
bin start.py
conf setting.py
log access.log
lib 包和模块
db
core src.py