zoukankan      html  css  js  c++  java
  • Day06:迭代器,生成器,生成表达式,面向过程编程,包及常用模块

    今日内容:
    1.迭代器(****)
    2.生成器(***)
    3.生成器表达式(*****)
    4.面向过程编程(*****)
    5.包的使用(***)
    6.常用模块
        logging (*****)
        re (*****)

    一.迭代器

    1.什么是迭代器
        迭代器就是迭代取值的工具
        迭代是一个重复的过程,但是每一次重复都是基于上一次的结果而进行的
    2.为何要用迭代器
        针对没有索引的数据类型,如:字典,集合,文件,要想迭代取出其中包含的一个个的值
        python解释器必须提供一种能够不依赖于索引的迭代取值工具
    3.如何用迭代器
        可迭代类型的对象:但凡内置有__iter__方法的对象都可以称为可迭代对象
        x=1
        y=1.3
        #以下都是可迭代对象
        str1='hello'
        list1=['a','b','c']
        t1=('a','b','c')
        dic={'x':1,'y':2}
        set1={'m','n'}
        f=open('a.txt',mode='rt',encoding='utf-8')
        #对于可迭代对象来说,调用可迭代对象.__iter__()方法,得到的就是其迭代器对象
    迭代器对象:
    1.内置有__iter__方法,调用迭代器对象__iter__方法得到的仍然是迭代器本身
      ps:文件对象本身就是一个迭代器对象,即同时也内置有__next__方法
    2.内置有__next__方法
    迭代器优点:
      1.提供一种能够不依赖索引的、通用的迭代取值方式
    补充:for循环可以称之为迭代器循环
    for item in list1:
        print(item)
      for循环的工作流程
        a.调用in后面那个对象的__iter__方法,拿到一个迭代器对象
        b.调用迭代器对象的__next__方法,拿到一个返回值赋值给变量item
        c.循环往复,直到抛出异常,for循环会自动捕捉异常结束循环
      2.节省内存

    迭代器的缺点:
      1.针对同一个迭代器对象只能取完一次,不如按照索引或key取值方式灵活
      2.无法预测迭代器对象所包含值的个数
    1 l=['alex','andy','lily']
    2 count=0
    3 while count<len(l):
    4     print(l[count])
    5     count+=1

    输出:

    alex
    andy
    lily

     1 #对于可迭代对象来说,调用可迭代对象.__iter__()方法,得到的就是其迭代器对象
     2 dic={'x':1,'y':2}
     3 iter_dic=dic.__iter__() #iter_dic=iter(dic) 作用相同
     4 print(iter_dic)
     5 k1=iter_dic.__next__() #k1=next(iter_dic) 作用相同
     6 print(k1,type(k1))
     7 k2=iter_dic.__next__() #k2=next(iter_dic) 作用相同
     8 print(k2,type(k2))
     9 try:
    10     next(iter_dic)
    11 except StopIteration:
    12     print('==========>')

    输出:

    <dict_keyiterator object at 0x0000021B9D9370E8>
    x <class 'str'>
    y <class 'str'>
    ==========>

    1 dic={'x':1,'y':2}
    2 iter_dic=iter(dic)
    3 while True:
    4     try:
    5         k=next(iter_dic)
    6         print(k)
    7     except StopIteration:
    8         break

    输出:

    x
    y

    1 list1=['a','b','c']
    2 iter_list=iter(list1)
    3 while True:
    4     try:
    5         k=next(iter_list)
    6         print(k)
    7     except StopIteration:
    8         break

    输出:

    a
    b
    c

    二.生成器

    1.什么是生成器
        在函数内但凡出现yield关键字,再调用函数就不会触发函数体代码的执行了
        会得到一个返回值,该返回就是一个生成器对象
        而生成器本身就是一个迭代器
    2.为何要用生成器
        生成器是自定义的迭代器
    3.如何用生成器
     
    总结yield
    1.提供一种自定义迭代器的方式
    2.可以用于返回值
        yield与return区别
        相同点:都可以用于返回值,个数以及类型都没有限制
        不同点:yield可以返回多次值,return只能返回一次值
    3.函数暂停及继续执行的状态是由yield保存的
     1 def foo():
     2     print ('first')
     3     yield 1
     4     print ('second')
     5     yield 2
     6     print ('third')
     7     yield 3
     8     print ('fourth')
     9 g=foo() #g是生成器=》就是迭代器
    10 print (g.__next__()) #会触发g对应函数的函数体代码执行,直到碰到一个yield就暂停住,就该yield后的值当作本地__next__()的返回值
    11 print (g.__next__())
    12 print (g.__next__())

    输出:

    first
    1
    second
    2
    third
    3

    1 def my_range(start,stop,step=1):
    2     while start < stop:
    3         yield start
    4         start+=step
    5 for i in my_range(1,10,2):
    6     print (i)

    输出:

    1
    3
    5
    7
    9

     1 #yield关键字表达式形式的应用
     2 #x=yield
     3 def dog(name):
     4     print('dog[%s]准备开吃' %name)
     5     while True:
     6         food=yield
     7         print('dog[%s]吃了:%s' %(name,food))
     8 dg1=dog('haha')
     9 #强调:针对表达式形式的yield,在使用生成器时必先send(None),相当于先完成一个初始化操作
    10 next(dg1)
    11 #send有两个功能
    12 #1.为当前暂停位置的yield赋值
    13 #2.与next的效果一样,不传值默认传None
    14 res=dg1.send('骨头')
    15 print(res)

    输出:

    dog[haha]准备开吃
    dog[haha]吃了:骨头
    None

     1 def dog(name):
     2     print('dog[%s]准备开吃' %name)
     3     food_list=[]
     4     while True:
     5         food=yield food_list
     6         food_list.append(food)
     7         print('dog[%s]吃了:%s' %(name,food))
     8 dg1=dog('haha')
     9 #强调:针对表达式形式的yield,在使用生成器时必先send(None),相当于先完成一个初始化操作
    10 next(dg1)
    11 #send有两个功能
    12 #1.为当前暂停位置的yield赋值
    13 #2.与next的效果一样,不传值默认传None
    14 res=dg1.send('骨头')
    15 print(res)
    16 res=dg1.send('馒头')
    17 print(res)

    输出:

    dog[haha]准备开吃
    dog[haha]吃了:骨头
    ['骨头']
    dog[haha]吃了:馒头
    ['骨头', '馒头']

    查询/etc 下所有文中含‘python’的文件,迭代查询

    grep -rl 'python' /etc

    三.生成器表达式

    1 #生成器表达式
    2 l=[i**2 for i in range(1,11)]
    3 print (l)
    4 
    5 names=['alex','andy','tom']
    6 #l=[name.upper() for name in names if name != 'andy']
    7 l=(name.upper() for name in names if name != 'andy')
    8 #print(l)
    9 print(next(l))

    输出:

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    ALEX

    四.面向过程编程

    1.核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么
        基于该思想编程写程序就好比在设计一条流水线,是一种机械式的思维方式
        优点:复杂的问题流程化,进而简单化
        缺点:牵一发而动全身,扩展性差

     1 def communicate():
     2     name=input('username>>').strip()
     3     pwd=input('password>>').strip()
     4     return (name,pwd)
     5 def auth(name,pwd):
     6     if name =='andy' and pwd =='123':
     7         return True
     8     else:
     9         return False
    10 def index(res):
    11     if res:
    12         print('welcome')
    13     else:
    14         print('login fail')
    15 def main():
    16     user,pwd=communicate()
    17     res=auth(user,pwd)
    18     index(res)

    五.包的使用

    1.什么是包
        包本质就是一个包含有__init__.py文件夹,文件夹是用来组织文件
        强调,包以及包下所有的文件都是用来被导入使用的,没有一个文件时用来被直接运行
        因为包其实时模块的一种形式而已
    2.import p1
        a.创建p1的名称空间
        b.执行p1下的__init__.py文件的代码,将执行过程中产生的名字都丢到名称空间中
        c.在当前执行文件中拿到一个名字p1, p1指向__init__.py的名称空间
    3.包内模块的绝对导入与相对导入
        绝对导入:每次导入都是以最顶级包为起始开始导入
        相当导入:相对于当前所在的文件,.代表当前所在的文件,..代表上一级
            强调:相对导入只能在被导入的模块中使用
            在执行文件中不能用.或者..的导入方式
    4.注意
        但凡在点的左边必须时一个包

     1 def f1():
     2     pass
     3 def f2():
     4     pass
     5 def f3():
     6     pass
     7 def f4():
     8     pass
     9 def f5():
    10     pass
    11 def f6():
    12     pass

    六.常用模块

    1.logging

    
    
    logging模块包含四种对象:logger、filter、handler、formatter
    
    
    1)logger对象负责产生日志
      logger1=logging.getLogger('交易日志')
    2)filter过滤
    3)handler对象需要与logger对绑定,用来接收logger对象传过来的日志,控制打印到不同的地方(不同的文件、终端)
      fh1=logging.FileHandler(filename='a1.log',encoding='utf-8')
      fh2=logging.FileHandler(filename='a2.log',encoding='utf-8')
      sh=logging.StreamHandler()
    4)formmter对象需要与handler对象绑定,用于控制handler对象的日志格式
      formmater1=logging.Formatter(
          fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
          datefmt='%Y-%m-%d %H:%M:%S %p'
    )
      formmater2=logging.Formatter(
          fmt='%(asctime)s - %(levelname)s :  %(message)s',
          datefmt='%Y-%m-%d %H:%M:%S %p'
    )
    # 设置日志级别:logger与handler两层关卡都放行,日志最终才放行
      logger1.setLevel(10)
      fh1.setLevel(10)
      fh2.setLevel(40)
      sh.setLevel(10)
    # 建立logger对象与handler对象的绑定关系
      logger1.addHandler(fh1)
      logger1.addHandler(fh2)
      logger1.addHandler(sh)
    # 建立handler对象与formmater对象的绑定关系
      fh1.setFormatter(formmater1)
      fh2.setFormatter(formmater1)
      sh.setFormatter(formmater2)
    # 使用logger1对象产生日志,打印到不同的位置
    # logger1.debug('alex给egon转账1亿')
      logger1.warning('alex可能要赔一个亿')
     1 import logging
     2 
     3 logging.debug('调试debug')
     4 logging.info('消息info')
     5 logging.warning('警告warn')
     6 logging.error('错误error')
     7 logging.critical('严重critical')
     8 
     9 '''
    10 WARNING:root:警告warn
    11 ERROR:root:错误error
    12 CRITICAL:root:严重critical
    13 '''

    输出:

    WARNING:root:警告warn
    ERROR:root:错误error
    CRITICAL:root:严重critical

    完整的日志内容:

    1.时间
    2.级别
    3.类型

    2.re模块

     1 import re
     2 
     3 print(re.findall('w','hello123 -_*()')) #匹配字母数字下划线
     4 print(re.findall('W','hello123 -_*()')) #匹配非字母数字下划线
     5 print(re.findall('andy','helloandy123 -_andy*()')) #匹配andy
     6 print(re.findall('^andy','helloandy123 -_andy*()')) #匹配andy开头
     7 print(re.findall('andy$','helloandy123 -_andy')) #匹配andy结尾
     8 print(re.findall('s','h 	ell
    lo')) #匹配任意空字符
     9 print(re.findall('	','h 	ell
    lo')) #匹配制表符
    10 print(re.findall('
    ','h 	ell
    lo')) #匹配换行符
    11 print(re.findall('S','h 	ell
    lo')) #匹配任意非空字符
    12 print(re.findall('d','hello123 -_*()'))#匹配数字
    13 #.代表匹配除了换行符意外的任意单个字符
    14 print(re.findall('a.c','abc a*c a1c a
    c aaaaac  a c hello123 -_*()'))#.匹配除了换行符以外的任意单个字符
    15 print(re.findall('a.c','abc a*c a1c a
    c aaaaac  a c hello123 -_*()',re.DOTALL))#.匹配任意单个字符
    16 #[]代表匹配我们自定范围的任意一个字符,[]减号必须放在最后
    17 print(re.findall('d[+*/-]d','1+3 a1!3sdf 2*3 1/4 2-3 a
    c aaaaac  a c hello123 -_*()'))#.匹配除了换行符以外的任意单个字符
    18 print(re.findall('a[0-9]c','a1c a2c  a11c  abc a*c a9c hello123 -_*()'))#.匹配除了换行符以外的任意单个字符
    19 print(re.findall('a[A-Za-z]c','a1c a2c  a11c  abc a*c a9c hello123 -_*()'))#.匹配除了换行符以外的任意单个字符

    输出:

    ['h', 'e', 'l', 'l', 'o', '1', '2', '3', '_']
    [' ', '-', '*', '(', ')']
    ['andy', 'andy']
    []
    ['andy']
    [' ', ' ', ' ']
    [' ']
    [' ']
    ['h', 'e', 'l', 'l', 'l', 'o']
    ['1', '2', '3']
    ['abc', 'a*c', 'a1c', 'aac', 'a c']
    ['abc', 'a*c', 'a1c', 'a c', 'aac', 'a c']
    ['1+3', '2*3', '1/4', '2-3']
    ['a1c', 'a2c', 'a9c']
    ['abc']

     1 #重复匹配
     2 #? :代表左边那一个字符出现0次或1次
     3 print(re.findall('ab?','b ab  abb abbb bbbba'))
     4 print(re.findall('ab{0,1}','b ab  abb abbb bbbba'))
     5 
     6 
     7 #*  :代表左边那一个自处出现0次或无穷次,如果没有可以凑活,但如果>1个,有多少就必须拿多少
     8 print(re.findall('ab*','b ab  abb abbb bbbba'))
     9 print(re.findall('ab{0,}','b ab  abb abbb bbbba'))
    10 
    11 
    12 #+  :代表左边那一个字符出现1次或无穷次,至少要有一个,但如果有>1个,有多少就必须拿多少
    13 print(re.findall('ab+','b ab  abb abbb bbbba'))
    14 print(re.findall('ab{1,}','b ab  abb abbb bbbba'))
    15 
    16 
    17 #{n,m}:代表左边那一个字符出现n次到m次,至少要有n个,但如果有>n个,就拿<=m个
    18 print(re.findall('ab{2,5}','b ab  abbbbbbbbbbb  abb  abbbbb bbbbbba'))
    19 
    20 #.* :匹配任意0个或无穷个任意字符,默认贪是婪匹配,找离a最远的c
    21 print(re.findall('a.*c','hello a123124cqweqwec+'))
    22 
    23 #.*? :匹配任意0个或无穷个任意字符,默认是非贪婪匹配,找离a最近的c
    24 print(re.findall('a.*?c','hello a123124cqweqwec+aasdasdc'))
    25 
    26 print(re.findall('href="(.*?)"','<div class="div1"><a href="https://www.baidu.com">"点我啊"</a></dic><div class="div1"><a href="https://www.baidu.com">"点我啊"</a></dic><div class="div1"><a href="https://www.python.com">"点我啊"</a></dic>'))
    27 # ?:
    28 print(re.findall('compan(ies|y)','Too many companies have gone bankrupt, and the nnext one is my company'))
    29 print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt, and the nnext one is my company'))
    30 
    31 #[]内^代表取反
    32 print(re.findall('a[^0-9]c','hello a1c abc a123124cqweqwec+'))
    33 
    34 print(re.findall('a\c','ac a1c abc aac'))
    35 print(re.findall(r'a\c','ac a1c abc aac'))

    输出:

    ['ab', 'ab', 'ab', 'a']
    ['ab', 'ab', 'ab', 'a']
    ['ab', 'abb', 'abbb', 'a']
    ['ab', 'abb', 'abbb', 'a']
    ['ab', 'abb', 'abbb']
    ['ab', 'abb', 'abbb']
    ['abbbbb', 'abb', 'abbbbb']
    ['a123124cqweqwec']
    ['a123124c', 'aasdasdc']
    ['https://www.baidu.com', 'https://www.baidu.com', 'https://www.python.com']
    ['ies', 'y']
    ['companies', 'company']
    ['abc']
    ['a\c']
    ['a\c']

     1 print(re.findall(r'andy','ac andy a1c abc aac andy '))
     2 #re.search从左往右匹配,成功一个就结束,不成功最后返回None
     3 print(re.search(r'andy','ac andy a1c abc aac andy '))
     4 print(re.search(r'andy','ac andy a1c abc aac andy ').group())
     5 obj=re.search('href="(.*?)"','<div class="div1"><a href="https://www.baidu.com">"点我啊"</a></dic><div class="div1"><a href="https://www.baidu.com">"点我啊"</a></dic><div class="div1"><a href="https://www.python.com">"点我啊"</a></dic>')
     6 print(obj.group())
     7 #以下同等作用
     8 print(re.search(r'^andy','ac andy a1c abc aac andy '))
     9 print(re.match(r'andy','ac andy a1c abc aac andy '))
    10 #切分
    11 msg='root:x:0:0::/root:/bin/bash'
    12 print(re.split('[:/]',msg))
    13 #替换
    14 print(re.sub('andy','haha','andy hello andy'))
    15 print(re.sub('^andy','haha','andy hello andy'))
    16 print(re.sub('andy$','haha','andy hello andy'))

    输出:

    ['andy', 'andy']
    <_sre.SRE_Match object; span=(4, 8), match='andy'>
    andy
    href="https://www.baidu.com"
    None
    None
    ['root', 'x', '0', '0', '', '', 'root', '', 'bin', 'bash']
    haha hello haha
    haha hello andy
    andy hello haha

    1 obj=re.compile('href="(.*?)"')
    2 
    3 msg1='<div class="div1"><a href="https://www.baidu.com">点我啊</a></div><div class="div1"><a href="https://www.python.org">点我啊</a></div>'
    4 # print(re.findall('href="(.*?)"',msg1))
    5 print(obj.findall(msg1))
    6 
    7 msg2='<div class="div1"><a href="https://www.sina.com.cn">点我啊</a></div><div class="div1"><a href="https://www.tmall.com">点我啊</a></div>'
    8 # print(re.search('href="(.*?)"',msg2).group(1))
    9 print(obj.search(msg2).group(1))

    输出:

    ['https://www.baidu.com', 'https://www.python.org']
    https://www.sina.com.cn

  • 相关阅读:
    go---weichart个人对Golang中并发理解
    go语言值得学习的开源项目推荐
    mysql17---增量备份
    mysql16---读写分离
    mysql15--垂直分表水平分表
    mysql14---手动备份
    mysql13---索引使用注意
    mysql12----explain
    mysql11---主键普通全文索引
    OpenOffice的简单安装
  • 原文地址:https://www.cnblogs.com/dingchuan/p/9388048.html
Copyright © 2011-2022 走看看