Python 文件和异常

Python 文件和异常

1、从文件中读取数据:

1.1、读取整个文件:

  • 每当需要分析或修改存储在文件中的信息时,读取文件都很有用,对数据分析应用程序来说尤其如此。

    • 首先再当前目录中创建一个.txt结尾的文本文件,内如如下:

      3.1415926535
      8979323846
      2643383279
      
    • 再.py文件中输入:

      with open('./test.txt') as file_obj:  # 当前目录名字test.txt文件
          contents = file_obj.read()
          print(contents)	
      # 输出结果如下:
      3.1415926535
      8979323846
      2643383279
      
    • 函数open(),要以任何方式使用文件——哪怕仅仅是打印其内容,都得先打开 文件,这样才能访问它

      • 函数open()接受一个参数:要打开的文件的名称。
      • Python在当前执行的文件所在的目录中查找指定的文件
      • 函数open()返回一个表示文件的对象。在这里,open(‘test.txt’)返回一个表示文件test.txt 的对象
      • 将这个对象存储在我们将在后面使用的变量中。
    • 关键字with 在不再需要访问文件后将其关闭

      • 到我们调用了open() ,但没有调用close();你也可以调用open() 和close() 来打开和关闭文件但这样做时,如果程序存在bug,导致close() 语句未执行,文件将不会关闭
    • 我们使用方法read()读取这个文件的全部内容,并将其作为一个长长的字符串存储在变量contents中.

1.2、文件路径:

  • 要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径 ,它让Python到系统的特定位置去查找。

  • 由于文件夹text_files位于文件夹python_work中,因此可使用相对文件路径来打开该文件夹中的文件

    • 在Linux和OSX中可以这样编写代码:

      with open('text_files/filename.txt') as file_object:
      
    • Windows系统中,在文件路径中使用反斜杠(\ )而不是斜杠(/ )

      with open('text_files\filename.txt') as file_object:
      
  • 还可以将文件在计算机中的准确位置告诉Python,这样就不用关心当前运行的程序存储在什么地方了。这称为绝对文件路径

    file_path = 'C:\Users\ehmatthes\other_files\text_files\filename.txt'
    with open(file_path) as file_object:
    
  • 注意  Windows系统有时能够正确地解读文件路径中的斜杠。如果你使用的是Windows系统,且结果不符合预期,请确保在文件路径中使用的是反斜杠。

1.3、逐行读取:

  • 读取文件时,常常需要检查其中的每一行:你可能要在文件中查找特定的信息,或者要以某种方式修改文件中的文本

    file_name = './test.txt' 
    with open(file_name) as file_obj:
        for line in file_obj:
            print(line)
    # 输出结果如下:
    3.1415926535
    
     8979323846
    
     2643383279
    
    • 我们将要读取的文件的名称存储在变量file_name 中,这是使用文件时一种常见的做法
    • 调用open() 后,将一个表示文件及其内容的对象存储到了变量file_object 中
    • 这里也使用了关键字with ,让Python负责妥善地打开关闭文件
  • 发现打印结果每行多出一个空行,因为read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行。

  • 要删除多出来的空行,可在print 语句中使用rstrip()

    file_name = './test.txt'
    with open(file_name) as file_obj:
        for line in file_obj:
            print(line.rstrip())
    # 输出结果如下:
    3.1415926535
     8979323846
     2643383279
    

1.4、创建一个包含文件各行内容的列表:

  • 使用关键字with 时,open() 返回的文件对象只在with 代码块内可用

  • 如果要在with 代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并
    在with代码块外使用该列表:

    file_name = './test.txt'
    with open(file_name) as file_obj:
        contents = file_obj.readlines()
        print(contents)
        
    for item in contents:
        print(item.rstrip())
    
    # 输出内容如下:
    ['3.1415926535\n', ' 8979323846\n', ' 2643383279']
    3.1415926535
     8979323846
     2643383279
    
    • 方法readlines() 从文件中读取每一行,并将其存储在一个列表中

1.5、使用文件的内容:

  • 将文件读取到内存中后,就可以以任何方式使用这些数据

    file_name = './test.txt'
    with open(file_name) as file_obj:
        contents = file_obj.readlines()
        print(contents)
    
    pi_string = ''
    for item in contents:
        pi_string += item.rstrip()
    
    print(pi_string)
    print(len(pi_string))
    # 输出结果如下:
    ['3.1415926535\n', ' 8979323846\n', ' 2643383279']
    3.1415926535 8979323846 2643383279
    34
    
    • 首先打开文件,并将其中的所有行都存储在一个列表中 contents
    • 我们创建了一个变量——pi_string ,用于存储圆周率的值
    • 一个循环将各行都加入pi_string ,并删除每行末尾的换行符
  • 为了删除两边的空格, 可以使用strip():

    file_name = './test.txt'
    with open(file_name) as file_obj:
        contents = file_obj.readlines()
        print(contents)
    
    pi_string = ''
    for item in contents:
        pi_string += item.strip()
    
    print(pi_string)
    print(len(pi_string))
    # 输出结果如下:
    ['3.1415926535\n', ' 8979323846\n', ' 2643383279']
    3.141592653589793238462643383279
    32
    
    
  • 注意:读取文本文件时,Python将其中的所有文本都解读为字符串。如果你读取的是数字,并要将其作为数值使用,就必须使用函数int() 将其转换为整数,或使用函数float() 将其转换为浮点数。

2、写入文件:

  • 保存数据的最简单的方式之一是将其写入到文件中。通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出也依然存在

2.1、写入空文件:

  • 将文本写入文件,你在调用open() 时需要提供另一个实参

    file_name = './test.txt'
    with open(file_name, 'w') as file_obj:
        file_obj.write('I love Python')
    # 将test.txt文件打开会发现
    I love Python # 已经写入进去了
    
    • 调用open() 时提供了两个实参:
      • 第一个实参也是要打开的文件的名称
      • 第二个实参('w' )告诉Python,我们要以写入模式 打开这个文件
    • 打开文件时,可指定读取模式 ('r' )写入模式 ('w' )附加模式 ('a' )或让你能够读取和写入文件的模式('r+' )
      • 如果你省略了模式实参,Python将以默认的只读模式打开文件
      • 如果你要写入的文件不存在函数open() 将自动创建它
      • 写入('w' )模式打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空该文件。
    • 我们使用文件对象的方法write() 将一个字符串写入文件
  • 注意:Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,必须先使用函数str() 将其转换为字符串格式。

2.2、写入多行:

  • 函数write() 不会在你写入的文本末尾添加换行符,因此如果你写入多行时没有指定换行符

    file_name = './test.txt'
    with open(file_name, 'a+') as file_obj:
        file_obj.write('I love Python')
        file_obj.write('I love you')
    # 打开test.txt文件会发现
    I love PythonI love you # 发现两行内容挤在一起了
    
  • 要让每个字符串都单独占一行,需要在write() 语句中包含换行符:

    file_name = './test.txt'
    with open(file_name, 'w') as file_obj:
        file_obj.write('I love Python\n')
        file_obj.write('I love you')
    # 打开test.txt 文件会发现
    I love Python
    I love you #  跟我们预想的是一样的结果
    

2.3、附加到文件:

  • 如果你要给文件添加内容,而不是覆盖原有的内容,可以附加模式打开文件。

  • 附加模式打开文件时,Python不会在返回文件对象前清空文件,而你写入到文件的行都将添加到文件末尾

  • 如果指定的文件不存在,Python将为你创建一个空文件。

    file_name = './test.txt'
    with open(file_name, 'a') as file_obj:
        file_obj.write('I love Python\n')
        file_obj.write('I love java\n')
        file_obj.write('I love you')
    # 打开test.txt文件的时候,里面已经有一段内容了
    里面已经有一段内容了
    I love Python
    I love java
    I love you
    
    • 我们打开文件时指定了实参'a' ,以便将内容附加到文件末尾,而不是覆盖文件原来的内容

3、异常:

  • Python使用被称为异常的特殊对象来管理程序执行期间发生的错误
  • 每当发生让Python不知所措的错误时,它都会创建一个异常对象
  • 如果你编写了处理该异常的代码,程序将继续运行;如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告
  • 异常是使用try-except 代码块处理的。
    • try-except 代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用了try-except 代码块时,即便出现异常,程序也继续运行:显示你编写的友好的错误消息,而不是令用户迷惑的traceback。

3.1、处理ZeroDivisionError 异常:

  • 下面来看一种导致Python引发异常的简单错误。你可能知道不能将一个数字除以0

    print(6/0)
    # 会报错
    Traceback (most recent call last):
      File "C:/Users/lh9/PycharmProjects/request/my_test01.py", line 996, in <module>
        print(6/0)
    ZeroDivisionError: integer division or modulo by zero
    
    • 在上述traceback中,指出错误ZeroDivisionError:是一个异常对象。
    • Python无法按你的要求做时,就会创建这种对象。在这种情况下,Python将停止运行程序,并指出引发了哪种异常,而我们可根据这些信息对程序进行修改。

3.2、使用try-except代码块:

  • 当你认为可能发生了错误时,可编写一个try-except 代码块来处理可能引发的异常

    try:
        print(6/0)
    except ZeroDivisionError:
        print('0不能被用做除数')
    # 输出结果就是
    0不能被用做除数
    
    • 如果try 代码块中的代码运行起来没有问题,Python将跳过except 代码块
    • 如果try 代码块中的代码导致了错误,Python将查找这样的except 代码块,并运行其中的代码,即其中指定的错误与引发的错误相同

3.3、else代码块:

  • 通过将可能引发错误的代码放在try-except 代码块中,可提高这个程序抵御错误的能力。

  • 错误是执行除法运算的代码行导致的,因此我们需要将它放到try-except 代码块中。

  • 这个示例还包含一个else 代码块依赖于try 代码块成功执行的代码都应放到else 代码块中

    while True:
        First = input('First number:')
        if First == 'q':
            break
        Second = input('\nSecond number:')
    
        try:
            answer = int(First) / int(Second)
        except ZeroDivisionError:
            print('0不能是被除数')
    
        else:
            print('成功输出')
            print(answer)
    
    • Python尝试执行try 代码块中的代码;
      • 只有可能引发异常的代码才需要放在try 语句中。
      • 有时候,有一些仅在try 代码块成功执行时才需要运行的代码;
      • 这些代码应放在else 代码块中。
    • except 代码块告诉Python,如果它尝试运行try 代码块中的代码时引发了指定的异常,该怎么办。

3.4、处理FileNotFoundError 异常:

  • 使用文件时,一种常见的问题是找不到文件

  • 你要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本就不存在。

  • 对于所有这些情形,都可使用try-except 代码块以直观的方式进行处理。

    filename = 'alice.txt'
    with open(filename) as f_obj:
    contents = f_obj.read()
    
    • python 无法读取不存在的文件,因此它引发一个异常:

      Traceback (most recent call last):
      File "alice.py", line 3, in <module>
      with open(filename) as f_obj:
      FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'
      
    • 在上述traceback中,最后一行报告了FileNotFoundError 异常,这是Python找不到要打开的文件时创建的异常

    • 这个错误是函数open() 导致的,因此要处理这个错误,必须将try 语句放在包含open() 的代码行之前:

      filename = 'alice.txt'
      try:
      with open(filename) as f_obj:
      contents = f_obj.read()
      except FileNotFoundError:
      msg = "Sorry, the file " + filename + " does not exist."
      print(msg)
      # 最终结果输出如下:
      Sorry, the file alice.txt does not exist.
      

3.5、失败时一声不吭:

  • 但并非每次捕获到异常时都需要告诉用户,有时候你希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行。

  • 要让程序在失败时一声不吭,可像通常那样编写try 代码块,但在except 代码块中明确地告诉Python什么都不要做。

  • Python有一个pass 语句,可在代码块中使用它来让Python什么都不要做

    try:
        print(6/0)
    except ZeroDivisionError:
        pass
        print('Except 抛出的异常什么都没有, 使用了pass语句')
    
  • pass 语句还充当了占位符,它提醒你在程序的某个地方什么都没有做,并且以后也许要在这里做些什么。

4、存储数据:

  • 模块json 让你能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件中的数据
  • 你还可以使用json 在Python程序之间分享数据。
  • 更重要的是,json数据格式并非Python专用的,这让你能够将以JSON格式存储的数据与使用其他编程语言的人分享

4.1、使用json.dump()和json.load():

  • 函数json.dump() 接受两个实参:要存储的数据以及可用于存储数据的文件对象。

    import json
    
    numbers = [2, 3, 5, 7, 11, 13]
    file_name = 'numbers.json'
    with open(file_name, 'w') as f_obj:
        json.dump(numbers, f_obj)
    # 打开nubers.json的文件 内容如下:
    [2, 3, 5, 7, 11, 13]
    
    • 我们先导入模块json ,再创建一个数字列表,指定了要将该数字列表存储到其中的文件的名称.
    • 通常使用文件扩展名.json来指出文件存储的数据为JSON格式
    • 我们使用函数json.dump() 将数字列表存储到文件numbers.json中。
  • 使用json.load() 将这个列表读取到内存中:

    import json
    
    numbers = [2, 3, 5, 7, 11, 13]
    file_name = 'numbers.json'
    with open(file_name) as f_obj:
        numbers = json.load(f_obj)
    
    print(numbers)
    # 输出结果如下:
    [2, 3, 5, 7, 11, 13]
    
    • 我们使用函数json.load() 加载存储在numbers.json中的信息,并将其存储到变量numbers 中。
    • 最后,我们打印恢复的数字列表,看看它是否与number_writer.py中创建的数字列表相同

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/84982377