高峰之巅 发表于 2018-8-14 06:41:46

python 第五天

  第一:
  1、协程函数:
  yield 是把函数的结果作为一个生成器。
  一个对象如果有iter和next方法,说明这个对象是一个迭代器、迭代器也是生成器。
  如果一个对象只有iter方法,那么这个对象是一个可迭代的对象。
  yield就是把函数的执行结果封装好iter和next方法、即可得到一个迭代器。
  他的功能和return功能类似、都可以返回值、但是不同的是return只能返回一次值、而yield可以返回多次值。
  函数暂停与运行的状态是又yield保存。
  例1、
  #yield
  def func(count):
  print('start')
  while True:
  yield   count
  count+=1
  g=func(10)
  print(g)
  print(next(g))
  print(next(g))
  例2:
  #yield的表达式应用。
  def eater(name):
  print('%s 说:我开动了' %name)
  while True:
  food=yield
  print('%s eat %s' %(name,food))
  res=eater('xz')
  print(next(res))
  print('================')
  res1=next(res)
  print(res1)
  >>
  xz 说:我开动了
  None
  ================
  xz eat None
  Non
  #yield的表达式、执行前必须先初始化、或者传值none
  #yield的表达式应用。
  def eater(name):
  print('%s 说:我开动了' %name)
  while True:
  food=yield
  print('%s 吃 %s' %(name,food))
  res=eater('xz')
  #第一阶段初始化,让生成器初始到一个位置
  next(res)**next的目的就是给yield一个none值
  #第二阶段、给yield传值
  res.send('包子')
  >>
  xz 说:我开动了
  xz 吃 包子
  xz 吃 骨头
  例3:
  #yield的表达式应用。
  def eater(name):
  print('%s 说:我开动了' %name)
  food_list=[]
  while True:
  food=yield food_list
  print('%s 吃 %s' %(name,food))
  food_list.append(food)
  res=eater('xz')
  #第一阶段初始化,让生成器初始到一个位置
  # next(res)
  res.send(None)
  #第二阶段、给yield传值
  print(res.send('包子'))
  print(res.send('菜汤'))
  >>
  xz 说:我开动了
  xz 吃 包子
  ['包子']
  xz 吃 菜汤
  ['包子', '菜汤']
  例4:
  #yield的表达式应用。
  def eater(name):
  print('%s 说:我开动了' %name)
  food_list=[]
  while True:
  food=yield food_list
  print('%s 吃 %s' %(name,food))
  food_list.append(food)
  def func():
  res=eater('xiaozhang')
  next(res)
  while True:
  food_inp=input('>>').strip()
  if notfood_inp:continue
  res1=res.send(food_inp)
  print(res1)
  func()
  >>
  xiaozhang 说:我开动了
  >>菜汤
  xiaozhang 吃 菜汤
  ['菜汤']
  >>
  #装饰器解决初始化的问题:
  def init(func):
  def warpper(*args,**kwargs):
  res=func(*args,**kwargs)
  next(res)
  return res
  return warpper
  @init
  def eater(name):
  print('%s 说:我开动了' %name)
  food_list=[]
  while True:
  food=yield food_list
  print('%s 吃 %s' %(name,food))
  food_list.append(food)
  def func1():
  res=eater('xiaozhang')
  while True:
  food_inp=input('>>').strip()
  if notfood_inp:continue
  res1=res.send(food_inp)
  print(res1)
  func1()
  2、面向过程:核心是过程二字、过程即解决问题的步骤。
  基于面向过程去设计程序就像一条工业流水线、是一种机械式的思维。
  优点:程序结构清晰、易读、流程化
  缺点:可扩展性差、一条流程线只解决一个问题
  应用场景:linux内核……、功能单一
  例1:使用面向过程的方法、实现grep -lr 'error' /dir/#显示文件中有error的列表文件
  import os
  def init(func):
  def warpper(*args,**kwargs):
  res=func(*args,**kwargs)
  next(res)
  return res
  return warpper
  第一阶段:找到文件的决定路径
  @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)
  第二阶段:打开文件
  @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
  for line in f:
  res=target.send((abspath,line))
  if res:break
  第四阶段:过滤
  @init
  def grep(patten,target):
  tag=False
  while True:
  abspath,line=yield tag
  tag = False
  if patten in line:
  target.send(abspath)
  tag=True
  第五阶段:打印该行属于的文件名
  @init
  def printer():
  while True:
  abspath=yield
  print(abspath)
  g = search(opener(cat(grep('error'.encode('utf-8'), printer()))))
  g.send(r'H:\test')
  3、递归函数:
  在一个函数的调用过程中、直接或者间接的调用了函数本身。
  递归效率比较低。
  #直接
  def func():
  print('from func')
  func()
  func()
  #间接
  def foo():
  print('from foo')
  bar()
  def bar():
  print('from bar')
  foo()
  foo()
  #递归
  def age(n):
  if n == 1:
  return 18
  else:
  return (age(n-1)+2)
  print(age(5))
  递归必须有一个明确的条件、python没有伪递归
  #递归
  l=,]]]
  def search(l):
  for item in l:
  if type(item) is list:
  search(item)
  else:
  print(item)
  search(l)
  #二分法
  l =
  #怎么判断某一个数字是否在列表内?
  def binary_search(l,num):
  print(l)
  if len(l) > 1:
  mid_index=len(l)//2
  if num > l:
  l=l
  binary_search(l,num)
  elif num < l:
  l=l[:mid_index]
  binary_search(l,num)
  else:
  print('find it')
  else:
  if l == num:
  print('find it')
  else:
  print('not exit')
  return
  binary_search(l,32)
  第二、模块与包
  1、模块就是包含一个了python定义和声明的文件、文件名就是模块名字加上py的后缀。
  2、 模块被导入默认就是执行模块文件
  3、导入模块干了那些事:
  A、执行源文件
  B、以原文件产生一个全局名称空间
  C、在当前位置拿到一个模块名指向2创建的名称空间
  4、from ....import
  A、优点:形式上不用使用源文件内的名字时无需加前缀,使用方便
  B、缺点:容易与当前文件的名称空间内的名字混淆。
  C、横杠只是对*起作用。有隐藏作用、可以使用__all__=[] 控制*的范围。
  5、模块的加载
  A、模块只是在第一次导入的时候才会执行,之后都是直接引用内存中已经加载的。
  import sys
  print(sys.modules)#存放的是已经加载到内存的模块字典
  模块的寻找顺序:
  内存中==>内置模块==>sys.path
  自定义的模块不能与py自带的模块重名。
  一个py文件有2中用途、脚本和模块。
  py文件当做脚本运行时:__name__等于__main__
  py文件当做模块调用时:__name__等于模块名
  包就是模块的另一种模式、包下面有一个_init_.py的文件夹,就是包。
  但是在这仅仅是py2.x的定义,在py3.x中没有_init_.py文件的文件夹也是包。
  B、无论是import还是from....import导入、只要遇到点(.)这都是包才有的导入语法、点的左面一定是一个包。
  包即模块、导入包就是导入模块。
  os模块:
  os.path.abspath(__file__)#获取当前文件的绝对路径。
  6、日志模块的参数:
  filename:指创建filehandler
  filemode:文件打开的方式:默认为a可以指定为w
  format:值handle使用的日志显示格式。
  datefmt:指定日期时间格式。
  level:设置日志的级别
  stream:用指定的stream创建streamHandler、
  日志的格式:
  %(name)s logger的名字、并非用户名
  %(levelno)s 数字形式的日志级别
  %(levelnames)s文本形式的日志级别
  %(pathname)s调用日志输出函数的模块的完整路径、可能没有
  %(filename)s调用日志输出函数的模块的文件名
  %(module)s 调用日志输出函数的模块名
  %(funcName)s 调用日志输出函数的函数名
  %(lineno)s 调用日志输出函数的语句所在代码行
  %(created)f 当前时间、用UNIX的标准时间的浮点表示
  %(relativeCreated)d输出日志信息时、自logger创建以来的毫秒数
  %(asctime)s 字符串形式的当前时间、默认格式是"2003-07-08 16:44:22,234"逗号后面的是毫秒
  %(thread)d 线程ID、可能咩有
  %(threadName)s 线程名、可能无
  %(process)d 进程ID、可能无
  %(message)s 用户输出的消息
  6、python正则:
  \w 匹配字母数字下及划线
  \W 匹配非字母数字下划线
  \s 匹配任意空白字符、等价于[\t\n\r\f]
  \S 匹配任意非空字符
  \d 匹配任意数字、等价于
  \D 匹配任意非数字
  \A 匹配字符串开始
  \Z 匹配字符串的结束、如果是存在换行、只匹配到换行钱的结束字符串。
  \z 匹配字符串结束
  \G 匹配最后匹配完成的位置
  \n 匹配一个换行符
  \t 匹配一个制表符
  ^匹配字符串的开头
  $匹配字符串的结尾
  .匹配任意字符、除了换行符、当re.DOTALL标记被指定时、则可以匹配包括换行符的任意字符。
  [..] 用来表示一组字符、单独列出、匹配a或者m或者k
  [^..] 不在[]中的字符、[^123] 匹配除了123之外的数字
  *匹配0个或者多个表达式
  +匹配一次或者多次表达式
  ? 匹配0次或者1次表达式
  {n} 匹配n次表达式
  {n,m} 匹配n次到m次表达式
  a|b匹配a或者b
  ()匹配括号内的表达式、也表示一个组。
页: [1]
查看完整版本: python 第五天