美文网首页
17 文件与异常处理

17 文件与异常处理

作者: 陪伴_520 | 来源:发表于2019-01-25 14:07 被阅读0次

    文中需要的所有程序和文件可从-->This is a llink下载

    本文主要从以下三点展开 :

    ①文件的读取 ②异常的处理 ③数据的简单操作


    一、文件的读取 --- with open(file_name / file_path) as f_obj:
    读取方式上可分为按文件名读取和按文件路径读取两种方式。
    • 按文件名读取 --- file_name = 'Alice.txt'
    file_name = 'Alice.txt'
    
    with open(file_name) as f_obj:   # f_obj是file_object的简写
        contents = f_obj.read()      #file.read()表示读取文件file的内容
        print(contents)
    
    • 按文件路径读取 --- file_path = 'home/PythonSudy/Alice.txt
    file_path = 'home/PythonSudy/Alice.txt'
    
    with open(file_path) as f_obj:
          contents = f_obj.read()
          print(contents)
    
    也可以逐行读取文件里的内容
    • 逐行读取文本文件内容 --- for line in f_obj:
    file_name = 'pi_digits.txt'
    
    with open(file_name) as file_object:
        for line in file_object:
            print(line)
    
    • 创建一个各行内容的列表 --- .readlines()
    file_name = 'pi_digits.txt'
    
    with open(file_name) as file_object:
        lines = file_object.readlines() 
    # readlines()函数创建一个读取的列表
    
    for line in lines:   
        print(line)
    # 注意for循环已在with open as代码块以外,这是因为readlines()函数的允许
    
    一个关于π的程序 --- 你的生日是否在 π 的前100万位中
    # 使用读取的文件 --- 将读取结果显示成一行
    file_name = 'pi_million_digits.txt'
    
    with open(file_name) as file_object:
        lines = file_object.readlines()
    
    pi_string = ''                   # 先创建一个空字符
    for line in lines:
        pi_string += line.strip()    # 累加读取的字符串列表(去除末尾的空字符)
    
    print(pi_string[:52] + "...")    # 读取列表前52项
    print(len(pi_string))            # len()函数显示字符串长度
    
    birthday = input("Enter your birthday, in the form mmddyy:")
    if birthday in pi_string:
        print("Your birthday appears in the first million digits of pi!")
    else:
        print("Your birthday does not appear in the first million digits of pi.")
    

    下面我们来尝试写入(更改文件内容) --- .write()

    • 覆盖原文件内容写入 --- 写入模式 ‘w’
    filename = 'programming.txt'
    
    with open(filename, 'w') as file_object:       # 以写入模式‘w’打开文件
        file_object.write("I love programming!\n") # 用write()函数开始写入
        #以写入模式运行时要特别注意,写入后只保留新写入的内容,擦除以前的内容
    
        file_object.write("I love creating new games!\n")
        #打开programming文件有时会发现新写入的内容挤在一行,我们需要注意加换行符
        file_object.write("I love Python!\n")
    
    • 不覆盖原文件内容 --- 附加模式 ‘a’
    #如果要是给文件添加内容而不是覆盖,可以使用附加模式'a'打开
    filename = 'programming.txt'
    
    with open(filename, 'a') as file_object:
        file_object.write("I also love finding meaning in large datasets.\n")
        file_object.write("I love creatinng apps that can run in a browser.\n")
    
    • 只读模式打开 --- 只读模式 ‘r’

    至此,学习了文件的基本读写,进一步的文件处理放在最后。

    下面我们先学习另一个有趣的问题 —— 发生异常时如何处理。


    异常处理 --- try: ... except ... else: ...

    • 一个最常见的异常 --- 除 0 错误
    #两个数的除法 --- 除数是0时自动提醒
    print("Give me two numbers, and I'll divide them.")
    print("Enter 'q' to quit.")
    
    while True:
        first_number = input("\nFirst number:")
        if first_number == 'q':
            break
        second_number = input("Second number:")
        if second_number == 'q':
            break
        #将可能引发错误的代码放在try-except代码块中
        try:
            answer = int(first_number) / int(second_number)
        except ZeroDivisionError:
            print("You can't divide by zero!")
        #如果try-except代码块中没有错误,将自动跳过这except这一段
        else:
            print(answer)
    

    异常处理的代码块儿是try -except或者try-except-else当程序运行到try-except代码块时先执行try下的内容,若有错误则执行except下的内容;若没有错误则跳过except下面的内容( 有else则执行else下的内容 )除 0 错误的标记是ZeroDivisionError —— except ZeroDivisionErroe:


    • 文件读取失败异常 --- 找不到指定的文件名
    # 假设查看一个目录下不存在的文件aliceX.txt --- 设置相应的反馈信息
    filename = 'aliceX.txt' # 这个文件压根不存在
    
    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
        msg = "Sorry, the file " + filename + " does not exist."
        print(msg)
    # 执行 try 下的内容,若无法正常执行就返回 except 下的内容(except需要指定错误类型)
    

    文件读取异常的标记是 FileNoFoundError

    其他错误标记可以通过其名称直接明白其含义,本文不再多提。

    但是有时候就算程序出现意料之中的异常,也不需要做什么

    例如读取一组文件时失败了一个,想让程序继续执行下去即可
    return None or pass
    # 编写一个计算文件含有多少个单词的函数 --- .split()函数
    
    def count_words(filename):
        """计算一个文件大概包含多少个单词"""
        try:
            with open(filename) as f_obj:
                contents = f_obj.read()
        except FileNotFoundError:          # ’找不到文件‘错误提醒功能
        #   print("No file name " + filename)
            pass
        else:
            # 计算文件大概包含多少个单词
            words = contents.split()
            num_words = len(words)
            print("The file " + filename + " has about " + str(num_words) + " words.")
    
    # 下面开始调用这个函数 --- 可以是多个文件的文件名列表
    filenames = ['alice.txt', 'little_women.txt', 'moby_dict.txt', 'siddhartha']
    # 注意最后一个故意未加.txt让程序找不到文件
    for filename in filenames:
        count_words(filename)
    # 结果可以看到,moby_dict.txt文件不存在 --- 并且提示了信息。
    
    # 但是有时候我们偏偏就不想让Python提醒这种”错误“ --- 失败时一声不吭。
    # 在 try-except 中插入 pass 或者 return None 即可。
    
    

    文中的split( )函数的作用是计算文件含有多少个字符


    下面我们来进一步使用文件 --- 存储文件和加载文件json模块

    • 创建一个数字列表文件并存储 --- json.dump( )
    # 创建一个.json文件并存入一个数字列表 --- json.dump( )
    
    import json
    # 导入json模块,使用其中的json.dump() --- 存储一组数;json.load() --- 将内容读取到内存中
    
    numbers = [2, 3, 5, 7, 11, 13]
    
    filename = 'numbers.json'           # 一般将使用的文件扩展名为.json来指明文件存储的数据为JSON格式的
    with open(filename, 'w') as f_obj:  # 我们以写入模式打开(或者创建)一个number.json的文件
         json.dump(numbers, f_obj)      # 用json.dump将列表内容写入f_obj(也就是number.json)
    
    # 运行后会发现已经创建了一个叫 number.json 的文件,其中的内容是列表[2, 3, 5, 7, 11, 13]
    # 要查看文件里的内容还需要json.load()函数将内容读取到内存中,见程序number.reader.py
    
    
    • 读取json文件 --- json.load( )
    # 读取json文件并显示内容 --- json.load()
    
    import json
    
    file_name = 'numbers.json'
    with open(file_name) as f_obj: # 还是先打开
        numbers = json.load(f_obj) # 然后将文件内容加载到内存 --- json.load()
    
    print(numbers)
    
    • 利用json模块的例子 --- 记住用户登录信息
    import json
    
    def get_store_username():
        """如果存储了用户名,就获取它"""
        filename = 'username.json'
        try:
            with open(filename) as f_obj:
                username = json.load(f_obj)
        except FileNotFoundError: # 若不存在,什么也不做(顺序执行) --- return None
            return None
        else:
            return username       # 否则就返回用户名
    
    def get_new_username():
        """提示用户输入用户名"""
        username = input("What's your name?")
        filename = 'username.json'
        with open(filename, 'w') as f_obj:
            json.dump(username, f_obj)  # 将username写入f_obj中
        return username
    
    def greet_user():
        """问候用户,并指出其名字"""
        username = get_store_username() # 调用以上函数获取用户名
        if username:                    # 直接if username判断是否获取到
            print("Welcome back, " + username + "!")
        else:
            username = get_new_username()
            print("We'll remember you when you come back, " + username + "!")
    
    # 下面直接调用函数greet_user()
    greet_user()
    
    

    这个 remember_me() 函数的最终版本,每个函数都执行单一而清晰的任务; 要编写出清晰而易于维护和扩展的代码,这种划分工作必不可少。


    下面是书后的一个小练习 ---- 记住你最喜欢的数字O(∩_∩)O

    • 首先是小程序段 favourite_number.pyremember_number.py
    import json
    
    number = input("Which number do you like best?")
    filename = 'favourite_number.json'
    with open(filename, 'w') as f_obj:
        json.dump(number, f_obj) # 将读取到的number信息写入f_obj中
    
    import json
    
    filename = 'favourite_number.json'
    with open(filename) as f_obj:
        number = json.load(f_obj)  # 将读取到的f_obj内容写入内存
        print("I konw your favourite number! It's " + number + ".")
    

    注意程序必须在同一工程目录下才可相互调用

    • 最终的完整程序 --- guess_number.py
    import json
    
    def get_store_favourite_number():
        """如果已经存储了数字,就获取它"""
        filename = 'favourite_number.json'
        # 试着打开相应的文件,若不存则返回空值None;存在就返回该文件的内容number
        try:
            with open(filename) as f_obj:
                number = json.load(f_obj)
        except FileNotFoundError:
            return None
        else:
            return number
    
    def get_new_favourite_number():
        """获取用户输入的数字"""
        number = input("Which number do you like best?")
        filename = 'favourite_number.json'
        with open(filename, 'w') as f_obj:
            json.dump(number, f_obj)  # 将读取到的number信息写入f_obj中
    
    
    def guess_result():
        """显示用户刚才输入的数字"""
        number = get_store_favourite_number()
        if number:
            print("I konw your favourite number! It's " + number + ".")
        else:
            get_new_favourite_number()
            print("I can get which is your favorite number next!")
    
    # 下面调用函数guess_result()
    # 如果文件favourite_number.json存在就直接显示结果;不存在就再问一次
    guess_result()
    
    

    最后附一张第10章内容的总结图(来自Xmind)

    第 10 章 文件和异常(总结).png

    一转眼又快过年了,再次祝大家猪年大吉 ! (* ̄(oo) ̄)

    240489918.jpg

    相关文章

      网友评论

          本文标题:17 文件与异常处理

          本文链接:https://www.haomeiwen.com/subject/mgqodqtx.html