17 文件与异常处理

2019-01-25  本文已影响0人  陪伴_520

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

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

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


一、文件的读取 --- with open(file_name / file_path) as f_obj:
读取方式上可分为按文件名读取和按文件路径读取两种方式。
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'

with open(file_path) as f_obj:
      contents = f_obj.read()
      print(contents)
也可以逐行读取文件里的内容
file_name = 'pi_digits.txt'

with open(file_name) as file_object:
    for line in file_object:
        print(line)
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()

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'打开
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")

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

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


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

#两个数的除法 --- 除数是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文件并存入一个数字列表 --- 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()

import json

file_name = 'numbers.json'
with open(file_name) as f_obj: # 还是先打开
    numbers = json.load(f_obj) # 然后将文件内容加载到内存 --- json.load()

print(numbers)
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

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 + ".")

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

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
上一篇下一篇

猜你喜欢

热点阅读