zoukankan      html  css  js  c++  java
  • Python(Head First)学习笔记:三

    3 文件与异常:调试、处理错误、迭代、改进、完善

     处理错误:利用Python的异常处理机制来处理异常情况。

        程序外部的数据:大多程序基本模型:首先输入数据,进行处理,然后存储、显示、打印或传输。

        Python从文件读取数据:Python的open()BIF就是用来与文件交互的,结合for语句使用,可以非常容易地读取数据。

          使用open()流程:读取文件数据时,Python会创建一个迭代器,从文件向代码输入数据行,一次传入一行数据。

     实例:

       打开终端,输入:python3

              import os

              os.getcwd()  #获取当前工作目录

              os.chdir('包含数据文件的文件夹目录')

              data=open('DataFile.txt')

              print(data.readline(),end='') #输出数据文件第一行数据

              print(data.readline(),end='') #输出数据文件第二行数据 

              data.seek(0)         #用seek()方法返回文件起始位置    

              for each_line in data:           #使用迭代的方法逐行输出数据文件

                 print(each_line,end=' ')

              data.close()               #关闭数据文件

    进一步查看数据

      split()方法返回一个字符串列表,然后赋值到一个目标标识符列表,

      通过将split()方法关联到输出变量,可以完成对数据文件的分割;

            如:A:I am a cool boy!

              用each_line.split(":")这句话可以分解成A和I am a cool boy!

              用(role,line_spoken) = each_line.split(“:”),来获取分解后的数据。

            实例:

              data = open('DataFile.txt')

              for each_line in data:

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

    了解数据的内容

      针对split()方法,上面的实例中,通过(role,line_spoken)=each_line.split(':')  这句代码,实现了将冒号":"分成两部分,

        然后分别赋值给role和line_spoken,但是当单行中出现多个冒号,就会报错:too many values to unpack。

      为了找到这个错误的原因,通过help(each_line.split)来查看:

        split()有一个可选参数,用于设置分割的数量,将其设置为1,则只会分解成两个部分,

        所以,可以将(role,line_spoken)=each_line.split(':') 这行代码改为(role,line_spoken)=each_line.split(':',1)即可。 

    更好的了解数据内容

      仍然针对split()方法,当数据行中没有冒号时,split(':',1)无法查找到,所以就会报错:need more than 1 value to unpack。

      由此引发了一个思考:如果数据文件中存在大量的这种没有冒号,或符合split()方法的判定,那么一定会报各种错误,该如何解决呢?

                有两个方向可以考虑:1 增加额外逻辑,确定是否需要调用split()方法;

                          2 不断调试,直到错误都解决。

      方法一:增加额外逻辑

          find()方法的引入,可以通过find()来尝试找出一个字符串中的子串,如果没有找到返回值是-1,如果找到了返回该子串在字符串中的索引位置。

          实例:>>>each_line = "I tell you, there'no such thing as a flying circus."

             >>>each_line.find(':')

            返回值为-1,因为字符串中没有包含冒号;

            修改字符串为:>>>each_line = "I tell you: there'no such thing as a flying circus."

                   >>>each_line.find(':')

            返回值为10,正好是字符串的第10个字符,从0开始计下标,空格也算一个字符。

        现在可以通过这个find()方法来改进上面的实例,具体如下:

              data = open('DataFile.txt')

              for each_line in data:

               if not each_line.find(':')==-1:  #这里增加了一个判断,即:如果找到了冒号,则继续执行,用到了not关键字。

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

              data.close()

        注:not关键字是对值进行取反的意思。

        问:为什么要用取反,而不是if each_line.find(':')>=0?这个有待进一步学习,感觉取反会更快些吧~

      方法二:处理异常

        当程序运行报错时,Python解释器会显示一个tranceback,后面跟一个错误消息,这个错误消息就异常(exception)。

        先尝试运行代码,然后处理可能发生的错误。

        try/except机制的引入

          基本格式:try:

                 代码内容(可能包含未知错误)

               except:

                 错误回复代码

        找出要保护的代码

          对于上面的实例可以改为:

              data = open('DataFile.txt')

              for each_line in data:

               try:                  #保护代码避开运行时的错误

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

               except:

                pass               #如果出现一个运行时错误,会执行这个代码

              data.close()

          注:对于列表,用中括号[]扩起来的是可以改变的列表;

            用小括号()扩起来的是不可以改变的列表,可以认为是一个常量列表。

      增加更多错误检查代码

          当数据文件突然丢失或破坏了,那么data=open('DataFile.txt')就会报错,所以有必要对数据文件的存在性进行检查:

            完善后的实例如下:

            方法一:

            import os

            if os.path.exists('DataFile.txt'):

              data = open('DataFile.txt')

              for each_line in data:

               try:                  #保护代码避开运行时的错误

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

               except:

                pass               #如果出现一个运行时错误,会执行这个代码

              data.close()

            else:

              print('The data file is misssing!')

            方法二:

            try:                             #保护代码避开运行时的错误

              data = open('DataFile.txt')

              for each_line in data:

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

              data.close()

          except:

                print(‘The data file is missing!’)        #文件丢失   

    问答:那么经过上面两种方法的实现,哪种方法更好一些呢?

       随着越来越多的错误和异常,第一种方法:增加额外代码和逻辑的复杂度也会随之增加,到后来就会比较乱;

                    第二种方法:采用异常处理机制,可以将主要注意力集中于代码的真正功能和实现。

          所以,总的来说,采用异常处理机制这种方式更合适。

    进一步的完善:特定指定异常

      通过对except代码指定错误类型,就可以把一般化的异常处理转换为具有特定性的处理,如下:

            try:                             #保护代码避开运行时的错误

              data = open('DataFile.txt')

              for each_line in data:

                try:

                (role,line_spoken)=each_line.split(':')  #需要缩进

                print(role,end='')           #缩进长度和上面一样

                print(' said: ',end='')

                print(line_spoken,end='')

              except ValueError:

                pass

              data.close()

          except IOError:

                print(‘The data file is missing!’)        #文件丢失   

        注:Python中不可改变的常量列表称为元组:tuple,一旦列表数据赋值到一个元组,就不能再改变,元组的符号是小括号(tuple)。

     

    ------------------------------------------The End of Third Chapter---------------------------------------------

  • 相关阅读:
    android中uiautomatorviewer monkeyrunner脚本地址
    python subprocess 获取执行结果
    blazor学习
    【.NET框架实战】IdentityServer4身份验证、授权
    命令行 查看当前.net和.net core版本
    github种的asp.net core源代码
    ASP.NET Core Web主机(IWebHostBuilder)
    EntityFrameworkCore教程:生成数据库表
    2021年规划
    [从0到1搭建ABP微服务]
  • 原文地址:https://www.cnblogs.com/heart2futrue/p/7552302.html
Copyright © 2011-2022 走看看