python day13 异常(基础) 、 迭代器 Iterator 和 生成器 Generator 、 生成器 Generator (python 2.5及之后)

目录:

异常(基础) 、 迭代器 Iterator 和 生成器 Generator 、 生成器 Generator (python 2.5及之后)

异常(基础) exception

什么是错误

错误是指由于逻辑或语法等导致一个程序无法正常执行的问题

错误的特点:

有些错误无法预知

什么是异常

异常是程序出错时标识的一种状态
当异常发生时,程序不会再向下执行,而转去调用此函数的地方待处理此错误并恢复为正常状态

异常的作用:

通知上层调用者有错误产生需要处理
用作信号

try语句的两种语法:

  1. try-except 语句
  2. try-finally 语句

try-except语句的语法:

  1. 例子:
    try:
    可能触发异常的语句
    except 错误类型1 [as 变量1]:
    异常处理语句1
    except 错误类型2 [as 变量2]:
    异常处理语句2
    except (错误类型3, 错误类型4,…):
    异常处理语句3

    except:
    异常处理语句other
    else:
    末发生异常的语句
    finally:
    最终语句
  2. 作用:
    偿试捕获异常,将程序转为正常状态并继续执行
  3. 示例见:

    1. try_except1.py:

      
      # 此示例示意用try-except语句来捕获异常
      
      def div_apple(n):
          """此示例用分苹果来示意捕获异常"""
          print("%d个苹果你想要分给几个人?" % n)
          s = input("请输入人数: ")
          cnt = int(s)  # <-此处可能会引起ValueError类型的错误
          result = n / cnt
          print("每个人分了", result, "个苹果")
      try:
          div_apple(10)
      except ValueError:
          print("发生了值错误,已转为正常状态")
      except ZeroDivisionError:
          print("发生了被零除的错误,苹果收回办公室")
      print("程序正常退出")
    2. try_except2.py:

      
      # 此示例示意用try-except语句来捕获异常
      
      def div_apple(n):
          """此示例用分苹果来示意捕获异常"""
          print("%d个苹果你想要分给几个人?" % n)
          s = input("请输入人数: ")
          cnt = int(s)  # <-此处可能会引起ValueError类型的错误
          result = n / cnt
          print("每个人分了", result, "个苹果")
      try:
          div_apple(10)
      except (ValueError, ZeroDivisionError):
          # 以上两个类型的错误都会用相同的方法来处理
          print("发生了错误,苹果被收回")
      print("程序正常退出")
    3. try_except3.py:

      
      # 此示例示意用try-except语句来捕获异常
      
      def div_apple(n):
          """此示例用分苹果来示意捕获异常"""
          print("%d个苹果你想要分给几个人?" % n)
          s = input("请输入人数: ")
          cnt = int(s)  # <-此处可能会引起ValueError类型的错误
          result = n / cnt
          print("每个人分了", result, "个苹果")
      try:
          div_apple(10)
      except ValueError:
          print("发生了值错误,苹果被收回")
      except:
          print("发生了除了值错误以外的错误,在此处处理")
      print("程序正常退出")
    4. try_except_as.py:

      
      # 此示例示意用try-except语句来捕获异常
      
      def div_apple(n):
          """此示例用分苹果来示意捕获异常"""
          print("%d个苹果你想要分给几个人?" % n)
          s = input("请输入人数: ")
          cnt = int(s)  # <-此处可能会引起ValueError类型的错误
          result = n / cnt
          print("每个人分了", result, "个苹果")
      try:
          div_apple(10)
      except ValueError as err:
          print("发生了值错误,苹果被收回")
          print("错误的值是:", err)
      
      print("程序正常退出")
    5. try_except_else.py:

      
      # 此示例示意用try-except语句来捕获异常
      
          def div_apple(n):
              """此示例用分苹果来示意捕获异常"""
              print("%d个苹果你想要分给几个人?" % n)
              s = input("请输入人数: ")
              cnt = int(s)  # <-此处可能会引起ValueError类型的错误
              result = n / cnt
              print("每个人分了", result, "个苹果")
          try:
              div_apple(10)
          except ValueError:
              print("发生了值错误,苹果被收回")
          else:
              # 此处语句只在没有发生异常时才会执行
              print("没有发生错误,苹果分完了")
          print("程序正常退出")
    6. try_except_else_finally.py:

       此示例示意用try-except语句来捕获异常
          def div_apple(n):
              """此示例用分苹果来示意捕获异常"""
              print("%d个苹果你想要分给几个人?" % n)
              s = input("请输入人数: ")
              cnt = int(s)  # <-此处可能会引起ValueError类型的错误
              result = n / cnt
              print("每个人分了", result, "个苹果")
          try:
              div_apple(10)
          except ValueError:
              print("发生了值错误,苹果被收回")
          else:
              # 此处语句只在没有发生异常时才会执行
              print("没有发生错误,苹果分完了")
          finally:
              # 此子句内的语句无论是否发生异常都一定会执行
              print("我一定会执行的!!!!")
          print("程序正常退出")
  4. 练习:
    写一个函数 get_score() 来获取用户输入的学生成绩(0~100的整数),如果输入出现错误,则此函数返回0,如果用户输入的数是0~100之间的数,返回这个数

    def get_score():

    score = get_score()
    print(‘学生的成绩是:’, score)

5, try-except语句语法说明:
1. as 子句是用于绑定错误对象的变量,可以省略
2. except 子句可以有一个或多个,但至少要有一个
3. else子句最多只能有一个,也可以省略
4. finally子句最多只能有一个,也可以省略

try-finally 语句

  1. 语法:
    try:
    可能触发异常的语句
    finally:
    最终语句

  2. 语法说明:
    finally 子句不可以省略
    一定不存在except 子句

  3. 作用:
    通常用try-finally 语句来做触发异常时必须要处理的事件,无论异常是否发生,finally 子句都会被执行
    注:
    try-finally 语句不会改变程序的(正常/异常)状态

raise 语句(类似java throw 向上抛出错误):

  1. 作用:
    触发一个错误,让程序进入异常状态
  2. 语法:
    raise 异常类型

    raise 异常对象
  3. 示例见:

    1. 没有使用raise示例:

      
      # 此示例示意raise语句的用法
      
      
      # 以下示意其它语言中不用异常机制,用返回值方式返回错误问题
      
      def make_except(n):
         # 假设n必须是 0~100之间的数
         print("begin...")
         if n > 100:  # 传过的来参数无效,怎么告诉调用者呢?
             return -1
         if n < 0:
             return -2
         print("end")
         return 0
      
      
      value = int(input("请输入一个整数:"))
      r = make_except(value)
      if r < 0:
         print("发生错误")
      else:
         print("程序正常完成")
      
    2. 使用raise示例:

      
      # 此示例示意raise语句的用法
      
      def make_except(n):
          # 假设n必须是 0~100之间的数
          print("begin...")
          if n > 100:  # 传过的来参数无效,怎么告诉调用者呢?
              raise ValueError
          if n < 0:
              raise ValueError("参数小于零错误:%d" % n)
          print("end")
      
      
      value = int(input("请输入一个整数:"))
      try:
          make_except(value)
      except ValueError as e:
          # print("make_except 抛出了错误,此异常状态已处理")
          # print("错误的值是:", e)
          print("发生错误")
      
      print("程序正常完成")

assert 语句(断言语句) 类似java抛出runtimeException 简化版本

  1. 语法
    assert 真值表达式, 错误数据(通常是字符串)
  2. 作用:
    当真值表达式为False时,用错误数据创建一个AssertionError类型的错误,并进入异常状态
    等同于:
    if 真值表达式 == False:
    raise AssertionError(错误数据)
  3. 示例见:

    def get_age():
        a = input("请输入年龄:")
        a = int(a)
        assert a < 140, "年龄不可能大于140!!!"
        assert a >= 0, "年龄不可能出现负数!!!"
        return a
    
    
    try:
        age = get_age()
    except AssertionError as err:
        print("发生了断言错误!错误对象是:", err)
        age = 0  #  做相应的处理
    print("您输入的年龄是: ", age)

为什么要用异常处理机制:

  1. 在程序调用层数较深时,向主调函数传递错误信息需要层层的 return 返回比较麻烦,所以用异常处理机制

  2. 示例:

    def f1():
        print("开始盖房子打地基...")
        return -1  # -1 代表挖出文物
        print("地基完工")
        return 0
    
    def f2():
        print("开始盖房子地面以上部分")
        return -2  # -2 代表要建高压线
        print("房子完工")
    
    def f3():
        """第二承包商打人干活"""
        r = f1()
        if r < 0:
            return r
        else:
            r2 = f2()
            return r2
    
    def build_house():
        r = f3()
        if r < 0:
            return r
        return 0
    
    
    r = build_house()
    if r == 0:
        print("房子盖好了")
    elif r == -1:
        print("房子没盖成,因为文物问题")
    elif r == -2:
        print("房子没盖成,因为高压线问题")
    
def f1():
        print("开始盖房子打地基...")
        raise ValueError("挖出文物")
        print("地基完工")

    def f2():
        print("开始盖房子地面以上部分")
        raise ZeroDivisionError("要建高压线")
        print("房子完工")

    def f3():
        """第二承包商打人干活"""
        f1()
        f2()

    def build_house():
        f3()


    try:
        build_house()
    except ValueError as err:
        print("房子没盖成,因为", err)
    except ZeroDivisionError as err:
        print("房子没盖成,因为", err)
    else:
        print("房子盖好了")

练习:

  1. 一个球从100米高度落下,每次落地后反弹高度为原高度的一半,再落下,
    1) 写程序算出皮球从第10次落地后反弹高度是多少?
    2) 球共经过多少米路径?

  2. 打印九九乘法表:
    1x1=1
    1x2=2 2x2=4
    1x3=3 2x3=6 3x3=9
    …..
    1x9=9 2x9=18 …….. 9x9=81

  3. 分解质因数:
    输入一个正整数,分解质因数:
    如输入: 90 则打印:
    90 = 2*3*3*5
    (质因数是指最小能被原数整除的素数(不包含1))

迭代器 Iterator

什么是迭代器:

  1. 迭代器是访问可迭代对象的一种方式,用迭代器可以访问可迭代对象
  2. 迭代器是指iter(可迭代对象) 返回的对象
  3. 迭代器可以用next(it) 函数获取可迭代对象的数据

迭代器函数iter和next

  1. iter(iterable) 从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
  2. next(iterator) 从迭代器iterator中获取下一个记录。如果无法获取下一条记录,则触发StopIterator异常

迭代器说明:

  1. 迭代器只能往前取值,不会后退
  2. 用iter函数可以返回一个可迭代对象的迭代器
  3. 示例:

    
    # iterator.py
    
    L = [2, 3, 5, 7]
    
    # 用for循环来访问可迭代对象中的数据
    
    for x in L:
        print(x)
    print('-------------------------')
    
    # 用while循环能否访问可迭代对象中的数据?
    
    
    # 第一步,让L给我们一个迭代器
    
    it = iter(L)
    
    # 第二步,循环用it迭代器去获取L中的数据,
    
    
    #   直到StopIteration为止
    
    while True:
        try:
            x = next(it)
            print(x)
        except StopIteration:
            break

练习:

已知有一个集合:
s = {“工商银行”, “建设银行”, “中国银行”, “农业银行”}
1. 用for 语句遍历集合中的元素并打印
2. 将上面的for 语句改写为while语句实现上面同样的功能
提示: 用iter和next 函数实现

生成器 generator (python 2.5及之后版本)

什么是生成器:

  1. 生成器是能够动态提供数据的对象,生成器对象也是可迭代对象

生成器有两种:

  1. 生成器函数
  2. 生成器表达式

生成器函数定义:

  1. 含有yield语句的函数是生成器函数,此函数被调用将返回一个生成器对象
    yield 翻译为(产生或生成)
  2. yield语句

    1. 语法:
      yield 表达式
    2. 说明:
      1. yield 用于def函数中,目的是将此函数作为生成器函数使用
      2. yield 用来生成数据,供next(it)函数使用
  3. 示例见:

    def myyield():
        yield 2
        yield 3
        yield 5
        yield 7
        print("生成器函数调用结束")
    
    gen = myyield()
    print(gen)  # gen绑定生成器对象,此对象为可迭代对象
    
    for x in gen:
        print(x)
    
    # it = iter(gen)  # 返回迭代器
    
    
    # x = next(it)
    
    
    # print(x)
    
    
    # print(next(it))
    
    def myyield():
        print("即将生成2")
        yield 2
        print("即将生成3")
        yield 3
        print("即将生成5")
        yield 5
        print("即将生成7")
        yield 7
        print("生成器函数调用结束")
    
    gen = myyield()
    it = iter(gen)
    print(next(it))
    print(next(it))  # myyield将从上一次停止的位置开始执行
  4. 高级示例:

      # 写一个生成器函数my_integer(n)生成 1 到 n的整数:
      def my_integer(n):
          i = 1  # 先初始化变量i将其设置为起始数
          while i < n:#循环判断是否已到终止点,如果未到则生成
               yield i  # 生成整数
               i += 1  # 控制循环条件
    
      for x in my_integer(5):
          print(x)  # 1  2  3  4
  5. 练习:
    写入一个生成器函数, myodd(start, stop) 用于生成start开始到stop结束(不包含stop)的所有奇数

    L = [x for x in myodd(1, 10)]
    print(L) # [1,3,5,7,9]
    for x in myodd(10, 20):
    print(x) # 11, 13, 15, 17, 19

生成器表达式:

  1. 语法:
    (表达式 for 变量 in 可迭代对象 [if 真值表达式])
    注: [] 内的if部分可以省略

  2. 作用:
    用推导式形式生成一个新的生成器

  3. 示例:
    gen = (x**2 for x in range(1, 5))
    it = iter(gen)
    next(it) # 1
    next(it) # 4
    next(it) # 9
    next(it) # 16
    next(it) # StopIteration

迭代工具函数:

  1. 迭代工具函数的作用是生成一个个性化的可迭代对象
  2. zip(iter1[, iter2, …]) 返回一个zip对象,此对象用于生成一个元组,此元组的个数是由最小的可迭代对象决定,元组内容是可迭代对象iter1和iter2中元素的组合
  3. enumerate(iterable[,start]) 生成带索引的枚举对象,返回的迭代类型为索引-值对(index-value)对,默认索引从零开始,也可以用start指定
  4. 示例见:

    1. zip.py:

      
      # 此示例示意zip函数的用法:
      
      
      numbers = [10086, 10000, 10010, 95588]
      name = ['中国移动', '中国电信', '中国联通']
      
      for t in zip(numbers, name):
          print(t)
    2. myzip.py:

      
      # 此示例来示意zip函数的内部实现方法
      
      def myzip(iter1, iter2):
          it1 = iter(iter1)
          it2 = iter(iter2)
          try:
              while True:
                  a = next(it1)
                  b = next(it2)
                  yield (a, b)
          except:
              pass
      numbers = [10086, 10000, 10010, 95588]
      name = ['中国移动', '中国电信', '中国联通']
      
      for t in myzip(numbers, name):
          print(t)
    3. zip2.py:

      
      # 此示例示意zip函数的用法:
      
      
      numbers = [10086, 10000, 10010, 95588]
      name = ['中国移动', '中国电信', '中国联通']
      
      for t in zip(range(1, 10000), numbers, name):
          print(t)
    4. enumerate.py:

      
      # 此示例示意enumerate的用法
      
      names = ['中国移动', '中国电信', '中国联通']
      for t in enumerate(names, 10):
          print(t)
  5. 练习:
    写一个程序,读入任意行的文字数据,当输入空行时结束输入
    打印带有行号的输入结果:
    如:
    请输入: hello<回车>
    请输入: home<回车>
    请输入: bye<回车>
    请输入: <回车>
    输出如下:
    第1行: hello
    第2行: home
    第3行: bye

字节串

作用:

存储以字节为单位的数据

说明:

字节串是不可改变的序列
字节是 0~255之间的整数

使用:

  1. 创建空的字节串的字面值
    b”
    b””
    b”””
    b”“”“”“
  2. 创建非空的字节串的字面值:
    B = b’hello’
    B = b”Hello”
    B = b”’abcd”’
    B = b”“”abcd”“”
    B = b’abc\n123’
    B = b’\x41\x42’
    b’\x16\x0d\x0d\x0a’

字节串的构造函数 bytes

bytes() 生成一个空的字节串 等同于b”
bytes(整数可迭代对象) 用可迭代对象初始化一个字节串
bytes(整数n) 生成n个值为0的字节串
bytes(字符串, encoding=’utf-8’) 用字符串的转换编码生成一个字节串

bytes 的运算:

+ += * *=
< <= > >= == !=
in / not in
索引和切片

in / not in 示例:

B = b’ABCDE’
0x41 in B # True

用于序列的函数:

len, max, min, sum, any, all 都可用于字节串

序列的方法:

详见:
>>> help(bytes)

bytes与 str的区别:

  bytes 存储字节(0~255)
  str   存储字符(Unicode值)

bytes 与 str转换

  1. 编码(encode)
    str ----> bytes
    b = s.encode(encoding='utf-8')

  2. 解码(decode)
    bytes ----> str
    s = b.decode(encoding='utf-8')

  3. 例:
    b = "你好".encode('utf-8')
    print(b)
    s = b.decode('utf-8')
    print(s)

字节数组 bytearray

可变的字节序列

创建函数 bytearray

  1. bytearray() 创建空的字节串
  2. bytearray(整数)
  3. bytearray(整型可迭代对象)
  4. bytearray(字符串, encode=’utf-8’)

操作:

  1. 常规操作
    + += * *=
    < <= > >= == !=
    in / not in
    索引 index / 切片 slice
    (字节数组可以索引和切片赋值,赋值规则同列表的索引和切片赋值相同)
  2. 例:
    ba = bytearray(b’abcdefg’)
    ba[0] = 0x41 # ba = bytearray(b’Abcdefg’)
    ba[1::2] = bytearray(b’BDF’) # 修改bdf为大写

  3. bytearray 的方法:
    BA代表bytearray
    BA.clear() 清空字节数组
    BA.append(n) 追加一个字节(n为0~255的整数)
    BA.remove(value) 删除第1个出现的字节,如果没有出现,则触发ValueError错误
    BA.reverse() 字节的顺序反转
    BA.decode(encoding=’utf-8’) 将bytearray转换为字符串
    BA.find(sub[, start[, end]]) 查找sub 子节数数组

  4. 练习:

    1. 用生成器函数生成斐波那契数列的前n个数:
      1 1 2 3 5 8 13 ….

      def fibonacci(n):

      yield ..
      1) 输出前 20 个数
      2) 求前 30 个数的和

    2. 写程序打印杨辉三角(只打印6层)
      1
      1 1
      1 2 1
      1 3 3 1
      1 4 6 4 1
      1 5 10 10 5 1

猜你喜欢

转载自blog.csdn.net/luohongtucsdn/article/details/80689565