zoukankan      html  css  js  c++  java
  • python -- 中

    九、文件和异常

    1、从文件中读取数据

      要使用文本文件中的信息,首先需要将信息读取到内存中,可以一次性读取文件的全部内容,也可以每次一行的方式逐步读取。

      ①读取整个文件

    #在当前目录下创建一个文本为 Nine-test.txt,然后使用代码读取这个文本
      
    with open('Nine-test') as file_object:
    contents = file_object.read()
    print(contents)

      

      函数 open() :要以任何方式使用文件,哪怕是仅仅打印其内容,都要先打开文件才能访问它,函数 open() 接受一个参数,为要打开文件的名称,Python 在当前执行的文件所在的目录中查找指定的文件,函数 open() 返回一个表示文件的对象,返回的是文本,Python 将这个对象存储在我们将在后面使用的变量中。

      关键字 with 在不需要访问文件后将其关闭。

      read() 到达文件末尾时返回一个空字符串,而将这个空字符串显示出来时就是一个空行,要删除多余的空行,可在 print 语句中使用 rstrip()

      ②文件路径

      要让Python打开不与程序文件位于同一个目录中的文件,需要提供文件路径。

    #在 Linux 和 OS X 系统中:( / )
    with open('text_files/filename.txt') as file_object:
    #在windows 系统中:(  )
    with open('text_filesfilename.txt') as file_object:

      可将计算机中准确的位置告诉Python,这称为绝对路径:

    file_path = 'C:/Users/rx801/PycharmProjects/study/Nine_test.txt'
    with open(file_path) as file_object:
        content = file_object.read()
        print(content)

      ③逐行读取

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

      例如:遍历一个包含天气的文件,并使用天气描述中包含字样 sunny 的行,或在新闻报道中查找包含标签<headline>的行。

      要以每次一行的方式检查文件,可对文件对象使用 for 循环。

    file_path = 'Nine-test'            #将要读取的文件名称存储在变量 filename 中,这是使用文件时一种常见的做法
    with open(file_path) as file_object:  #调用 open() 后,将一个表示文件及其内容的对象存储到了变量 file_object 中。
        for line in file_object:
            print(line.rstrip())        #使用 rstrip 消除每次输出后面的换行符。否则每行末尾都有两个换行符,一个来自文件,另一个来自print语句

     

      ④创建一个包含文件各行内容的列表

      使用关键字 with 时,open() 返回的文件对象只在 with 代码块内可用,如果要在 with 代码块外访问文件的内容,可在 with代码块内将文件的各行存储在一个列表中,并在 with 代码块外使用该列表;你可以立即处理文件的各个部分,也可推迟到程序后面再处理。

    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path) as file_object:
        line = file_object.readlines()
    
    for item in line:
        print(item.rstrip())

     

      readlines() 方法从文件中读取每一行,并将其存储在一个列表中,该列表存储在变量 line 中。

      ⑤使用文件的内容

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

    #圆周率值,创建一个字符串,包含文件中的所有数字,且没有任何空格
    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path) as file_object:
        line = file_object.readlines()
    pi_string = ''
    for item in line:
        pi_string += item.strip()  #拼接字符串
    print(pi_string)
    print(len(pi_string))

     

    #读取一百万位的文件,显示前50位,示例
    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path) as file_object:
        line = file_object.readlines()
    pi_string = ''
    for item in line:
        pi_string += item.strip()
    print(pi_string[:52] + "...")

     

      对于可处理的数据量,Python 没有任何限制;只要系统的内存足够多,想处理多少数据都可以。

    #检查生日是否包含在圆周率中
    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path) as file_object:
        line = file_object.readlines()
    pi_string = ''
    for item in line:
        pi_string += item.strip()
    birthday = input("Please input your Birthday: ")
    if birthday in pi_string:
        print("Yes,exist!")
    else:
        print("No,Not Exist!")

     

    2、替换文件内容 -- replace()

      方法 replace() 将字符串中的特定单词替换为另一个单词。

    message = "I Like Python"
    message.replace('Python','Linux')  #只是临时修改,永久修改需要将修改后的重新定义到变量中,message = message.replace('Python','Linux')

     

     3、写入文件

      保存数据最简单的方式之一是将其写入到文件中,通过将输出写入文件,即便关闭包含程序输出的终端窗口,这些输出依然存在,可以在程序结束运行后查看这些输出,可与别人分享输出文件,还可编写程序来将这些输出读取到内存中并进行处理。

      ①写入空文件

      要将文本写入文件,在调用 open() 时需要提供另一个实参,告诉Python要写入打开的文件

    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path,'w') as file_object:
        file_object.write("I Like Shell")
    with open(file_path) as file_a:
        print(file_a.read())

     

      在这个示例中,Python 调用了两个实参,第一个实参是要打开的文件的名称,第二个实参(‘w’)告诉Python要以写入模式打开这个文件,打开文件时,可指定读取模式(’r‘),写入模式('w'),附加模式('a'),能够读取和写入文件的模式('r+'),如果省略了默认实参,Python将以默认只读的模式打开文件。

      如果写入的文件不存在,函数open() 会创建它,使用('w')模式打开文件时,如果指定的文件已经存在,Python 将在返回文件对象前清空该文件。

      使用文件对象的方法 write() 将一个字符串写入文件。

      ※Python只能将字符串写入文本文件,要将数值数据存储到文本文件中,必须使用函数 str() 将其转换为字符串格式。

      ②写入多行

      函数 write() 不会在写入文本末尾添加换行符,因此在写入多行时需要指定换行符

    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path,'r+') as file_object:
        file_object.write("I Like Python.")
        file_object.write("I Like Linux.")

     

    #加入换行符
    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path,'r+') as file_object:
        file_object.write("I Like Python.
    ")
        file_object.write("I Like Linux.
    ")

     

      ③附加文件(追加文件)

      要给文件添加内容,而不是覆盖原有的内容,以附加模式打开文件,写入到文件的行都将添加到文件末尾,如果指定的文件不存在,Python将创建一个空文件。

    file_path = 'C:/Users/rx801/new_test.txt'
    with open(file_path,'a') as file_object:
        file_object.write("I Like Python.
    ")
        file_object.write("Python is very good!")

     

    #编写一个while 循环,提示用户输入其名字。用户输入其名字后,在屏幕上打印一句问候语,并将一条访问记录添加到文件guest.txt中。确保这 个文件中的每条记录都独占一行
    file_path = 'C:/Users/rx801/guest.txt'
    while True:
        name = input("Please input your name: ")
        if name == 'quit':
            break
        else:
            message = "Hello,"+name+".
    "
            print(message)
            with open(file_path,'a') as file_name:
                file_name.write(message)

     

     

    4、异常

      Python使用被称为异常的特殊对象来管理程序执行期间发生的错误。每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果编写了处理该异常的代码,程序将继续执行,如果未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。

      异常是使用 try-except 代码块处理的,try-except 代码块让 Python 执行指定的操作,同时告诉 Python 发生异常时怎么办,使用了 try_except 代码块时,即使出现异常,程序也将继续运行:显示你编写好的友好的错误信息,而不是令用户迷惑的 traceback。

      ①处理 ZeroDivisionError 异常

    print(5/0)
    
    ---------------------------------------------------------------------------
    ZeroDivisionError                         Traceback (most recent call last)
    <ipython-input-6-fad870a50e27> in <module>
    ----> 1 print(5/0)
    
    ZeroDivisionError: division by zero

      Python 无法按照你的要求做时,就会创建这种对象,Python 将停止运行程序,并指出引发了哪种异常。

      ②使用 try-except 代码块

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

    #处理 ZeroDivisionError 异常的 try-except 代码块类似这样:
    try:
        print(5/0)
    except ZeroDivisionError:
        print("You can't divide by zero!")

     

      将导致错误的代码行放在 try 代码块中,如果 try 代码块中的代码运行起来没有问题,Python将跳过except代码块;如果 try 代码块中的代码导致了错误,Python 将查找这样的except代码块,并运行其中的代码,即其中的错误与引发的错误相同。

      如果 try-except 后面还有其他代码,程序将接着运行。

      ③else 代码块

    while True:
        first_number = input("Please input first number: ")
        if first_number == 'quit':
            break
        second_number = input("Please input second number: ")
        if second_number == 'quit':
            break
        try:
            answer = int(first_number) / int(second_number)
        except:
            print("Error,Please input right number !")
        else:
            print(answer)

     

      ※ try-except-else 代码块的工作原理:Python 尝试执行 try 代码块中的代码,只有可能引发异常的代码才需要放在 try 语句中,仅在 try 代码块成功执行时才需要运行的代码放在 else 代码块中,except 代码块告诉 Python,尝试运行 try 代码块中的代码时引发了指定的异常怎么处理。

      ④处理 FileNotFoundError 异常

      使用文件时,一种常见的问题是找不到文件,要查找的文件可能在其他地方、文件名可能不正确或者这个文件根本不存在。

    file_path = 'C:/Users/rx801/Error.txt'
    with open(file_path) as file:
        print(file.read())
      
    ---------------------------------------------------------------------------
    FileNotFoundError                         Traceback (most recent call last)
    <ipython-input-14-a6e913997e4e> in <module>
          1 file_path = 'C:/Users/rx801/Error.txt'
    ----> 2 with open(file_path) as file:
          3     file.read()
    
    FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/rx801/Error.txt'

      使用 try-except 代码块

    file_path = 'C:/Users/rx801/Error.txt'
    try:
        with open(file_path) as file:
            content = file.read()
    except:
        print("Not Find This File!")
    else:
        print(content)

     

      ⑤分析文本

      方法 split() 以空格为分隔符将字符串分拆成多个部分,并将这些部分存储到一个列表中。

    title = 'C:/Users/rx801/new_test.txt'
    
    try:
        with open(title) as file:
            contents = file.read()
    except:
        print("file does not exist!")
    else:
        #计算文件包含多少单词 words
    = contents.split() num_words = len(words) print("The title has "+str(num_words)+" words!")

     

      使用 for 循环查看多个文件

    def count_words(title):
        try:
            with open(title) as file:
                contents = file.read()
        except:
            print("file does not exist!")
        else:
            words = contents.split()
            num_words = len(words)
            print("The title has "+str(num_words)+" words!")
    title = ['C:/Users/rx801/guest.txt','C:/Users/rx801/new_test.txt','C:/Users/rx801/abcd.txt']
    for item in title:
        count_words(item)

     

      ⑥失败时一声不吭

      在前一个示例中,有一个文件找不到,但并不是每次有异常都需要告诉用户,希望程序在发生异常时一声不吭继续运行,只需在except代码块告诉Python什么都不要做。

      使用 pass 语句可让发生异常时什么都不做。

    def count_words(title):
        try:
            with open(title) as file:
                contents = file.read()
        except:
            pass
        else:
            words = contents.split()
            num_words = len(words)
            print("The title has "+str(num_words)+" words!")
    title = ['C:/Users/rx801/guest.txt','C:/Users/rx801/new_test.txt','C:/Users/rx801/abcd.txt']
    for item in title:
        count_words(item)

     

      count() 方法可以确定特定的单词或短语在字符串中出现了多少次。

    pets = "dog,cat,fish,Cat,pig,CAT"
    pets.lower().count('cat')

     

      使用 lower() 将字符串变为小写,再查找相应的字符串。

    5、存储数据

      模块 json 能够将简单的Python数据结构转储到文件中,并在程序再次运行时加载该文件的数据,还可以使用 json 在 Python 程序之间分享数据。

      ①使用 json.dump() 和 json.load()

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

    import json
    numbers = [2,3,4,5,6,7]
    filename = 'C:/Users/rx801/numbers.txt'
    with open(filename,'w') as f_obj:
        json.dump(numbers,f_obj)

     

      使用函数 json.load() 将这个列表读取到内存中

    import json
    filename = 'C:/Users/rx801/numbers.txt'
    with open(filename) as f_obj:
        numbers = json.load(f_obj)
    print(numbers)

     

      读取前面写入的文件,使用函数 json.load() 加载存储在 numbers.json 中的信息,并将其存储到变量 numbers 中,最后打印数字列表。

    6、保存和读取用户生成的数据

      对于用户生成的数据,如果不以某种方式进行存储,等程序停止运行时用户的信息将丢失。

    #保存用户生成的数据
    import json
    filename = 'C:/Users/rx801/numbers.txt'
    username = input("What's your name? ")
    with open(filename,'w') as file_object:
        json.dump(username,file_object)
    
    #读取用户保存的数据
    import json
    filename = 'C:/Users/rx801/numbers.txt'
    try:
        with open(filename) as file_object:
            username = json.load(file_object)
    except FileNotFoundError:
        username = input("What's your name? ")
        with open(filename,'w') as f_obj:
            json.dump(filename,f_obj)
            print("welcome back: "+username)
    else:
        print(username)

     十、测试代码

      编写函数或类时,可为其编写测试。通过测试,可确定代码面对各种输入都能够按要求的那样工作,在程序中添加新代码时,也可以对其进行测试,确认它们不会破坏程序既有的行为,经常测试代码,在用户发现问题前找出它们。

    1、单元测试和测试用例

      Python标准库中的模块 unittest 提供了代码测试工具。

      单元测试用于核实函数的某个方面有没有问题。

      测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。良好的测试用例考虑到了函数可能接收到的各种输入。

      全覆盖式测试:用例包含一整套单元测试,涵盖了各种可能的函数使用方式。

    #main_user.py
    def greet_user(first_name,last_name):
        full_name = first_name+' '+last_name
        return full_name
    
    #Users.py
    import unittest
    from  main_user import greet_user
    class NameTestCase(unittest.TestCase):    #创建的类名随便起,但是最好和测试相关并包含Test,这个类必须继承unittest.TestCase类,这样Python才知道如何运行测试。
        '''测试 main_user.py'''
        def test(self):
            full_name = greet_user('Steven','Curry')
            '''使用unittest类的断言方法'''
            self.assertEqual(full_name,'Steven Curry')  #如果full_name的值与字符串'Steven Curry'相等,就OK,不相等就Fail
    unittest.main()

      assertEqual 方法是 unittest 类最有用的功能之一:一个断言方法,断言方法用来核实得到的结果是否与期望的结果一致。

     

    2、测试类

      ①各种断言方法

      Python 在unittest.TestCase类中提供了很多断言方法。断言方法检查你认为应该满足的条件是否确实满足。

      ②unittest Module中的断言方法:

  • 相关阅读:
    [译]Vulkan教程(03)开发环境
    [译]Vulkan教程(02)概况
    [译]Vulkan教程(01)入门
    CSharpGL(57)[译]Vulkan清空屏幕
    CSharpGL(56)[译]Vulkan入门
    CSharpGL(55)我是这样理解PBR的
    CSharpGL(54)用基于图像的光照(IBL)来计算PBR的Specular部分
    [译]背景:着色的物理和数学(4)
    [译]背景:着色的物理和数学(3)
    [译]背景:着色的物理和数学(2)
  • 原文地址:https://www.cnblogs.com/wqs-Time/p/14484989.html
Copyright © 2011-2022 走看看