Python 文件和异常

1 背景知识

  1. 你将学习处理文件,让程序能够快速地分析大量数据;
  2. 你将学习错误处理,避免程序在面对意外情形时崩溃;你将学习异常 ,它们是Python创建的特殊对象,用于管理程序运行时出现的错误;
  3. 你还将学习模块json ,它让你能够保存用户数据,以免在程序停止运行后丢失。

2 从文件中读取数据

with open('pi_digits.txt') as file_object:
    contents = file_object.read()
print(contents)

Warning

1、在这个程序中,注意到我们调用了open() ,但没有调用close() 。也可以调用open() 和close() 来打开和关闭
2、但这样做时,如果程序存在bug导致方法close() 未执行,文件将不会关闭。这看似微不足道,但未妥善关闭文件可能导致数据丢失或受损。如果在程序中过早调用close() ,你会发现需要使用文件时它已关闭 (无法访问),这会导致更多的错误。并非在任何情况下都能轻松确定关闭文件的恰当时机,但通过使用前面所示的结构,可让Python去确定:你只管打开文件,并在需要时使用它,Python自会在合适的时候自动将其关闭。

2.1 文件路径

2.1.1 相对路径

当前python 文件的相对路径。

with open('text_files/pi_digits.txt') as file_object:
    contents = file_object.read()
print(contents)

2.1.2 绝对路径

with open('D:/jikch/PycharmProjects/halloword/text_files/pi_digits.txt') as file_object:
    contents = file_object.read()
print(contents)
Warning

注意:在windows 下绝对路径路径分隔符是/ ,不是''
注意:在Linux 环境下绝对路径为'/home/ehmatthes/other_files/text_files/_filename_.txt'

2.2 逐行读取

filename ='text_files/pi_digits.txt'
with open(filename) as file_object:
    for line in file_object:
        print(line.rstrip())

Warning

rstrip() 去除空格。

2.3 包含大型文件

filename ='text_files/pi_million_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
pi_string = ''
for line in lines:
    pi_string += line.strip()

print(f"{pi_string[:52]}...")
print(len(pi_string))


2.4 截取文档中感兴趣的部分

filename ='text_files/pi_million_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
pi_string = ''
for line in lines:
    pi_string += line.strip()
birthday = input("Enter your birthday ,in the form mmddyy:")
if birthday in pi_string:
    print("Your birthday appears in the first millin digits of pi!")
else:
    print("your birthday does not appear in the first millin digits of pi.")

print(f"{pi_string[:52]}...")
print(len(pi_string))

2.5 练习题

练习10-1:Python学习笔记 在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的Python知识,其中每一行都以“In Python you can”打头。将这个文件命名为learning_python.txt,并存储到为完成本章练习而编写的程序所在的目录中。编写一个程序,它读取这个文件,并将你所写的内容打印三次:第一次打印时读取整个文件;第二次打印时遍历文件对象;第三次打印时将各行存储在一个列表中,再在with 代码块外打印它们。

filename = 'text_files/learning_python.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
for line in lines:
    replice=line.replace('Python', 'c')
    print(replice)

3 写入文件

with open(filename, 'r+') as file_object:
    file_object.write("I love programming.")
    contexts = file_object.read()

3.1.1 open 函数的实参

参数 说明
w 写入模式
r 读取模式
a 附加模式
r+ 读写模式
Warning

  1. 以写入模式('w')打开文件时千万要小心,因为如果指定的文件已经存在,Python将在返回文件对象前清空该文件的内容。
  2. Python只能将字符串写入文本文件。要将数值数据存储到文本文件中,
    必须先使用函数str() 将其转换为字符串格式.

3.2 写入多行

filename = 'text_files/programming.txt'
with open(filename, 'r+') as file_object:
    file_object.write("I love programming.\n")
    file_object.write("I love programming.\n")

with open(filename, 'r+') as file_object:
    contexts = file_object.read()
print(contexts)

3.3 附加到文件

filename = 'text_files/programming.txt'
with open(filename, 'a') as file_object:
    file_object.write("I alao love finding medning in large datasets.\n")
    file_object.write("I love creatings apps that can run in a browser.\n")

with open(filename, 'r+') as file_object:
    contexts = file_object.read()
print(contexts)

3.4 练习题

练习10-3:访客 编写一个程序,提示用户输入名字。用户做出响应后,将其名字写入文件guest.txt中。

filename = 'text_files/guest.txt'
username = str(input("please enter user name."))

with open(filename, 'w') as file_object:
    file_object.write(username)

with open(filename, 'r+') as file_object:
    contexts = file_object.read()
print(contexts)

练习10-4:访客名单 编写一个while 循环,提示用户输入名字。用户输入名字后,在屏幕上打印一句问候语,并将一条到访记录添加到文件guest_book.txt中。确保这个文件中的每条记录都独占一行

while True:
    filename = 'text_files/guest.txt'
    with open(filename, 'a') as file_object:
        username = str(input("please enter user name."))
        print(f"you can enter 'q' to quit")
        if username == 'q':
            break
        else:
            file_object.write(f"{username}\n")
            print(f"Hollo {username}")

4 异常

4.1 使用try-except 代码

try:
    print(5/0)
except ZeroDivisionError:
    print("you can't divide by zero!")

4.2 使用异常处理避免程序崩溃

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
    answer = int(first_number) / int(second_number)
    print(answer)

Warning
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:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can't divide by 0!")
    else:
        print(answer)


Warning

注意:你的else 是和try 匹配。所以不要看花眼哦。
try-except-else

4.3 处理FileNotFoundError 异常

filename = 'alice.txt'
try:
    with open(filename) as file_object:
        contents = file_object.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} does not exist.")

4.4 分析文本

filename = 'text_files/alice.txt'
try:
    with open(filename, encoding='utf-8') as file_object:
        contents = file_object.read()
except FileNotFoundError:
    print(f"Sorry, the file {filename} does not exist.")
else:
    words = contents.split()
    num_words = len(words)
    print(f"The file {filename} has about {num_words} words")

4.5 多个文本分析

Note

使用循环。

from function.count_words import count_words
filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']  
for filename in filenames:  
count_words(filename)
from function.count_words import count_words
filename='text_files/alice.txt'
count_words((filename))

4.6 报错过滤

def count_words(filename):
    try:
        with open(filename, encoding='utf-8') as file_object:
            contents = file_object.read()
    except FileNotFoundError:
        pass
#        print(f"Sorry, the file {filename} does not exist.")
    else:
        words = contents.split()
        num_words = len(words)
        print(f"The file {filename} has about {num_words} words")

Warning

可以通过pass标记如果发生异常,则跳过异常,什么错误都不报。

4.7 练习题

练习10-6:加法运算 提示用户提供数值输入时,常出现的一个问题是,用户提供的是文本而不是数。在此情况下,当你尝试将输入转换为整数时,将引发ValueError 异常。编写一个程序,提示用户输入两个数,再将其相加并打印结果。在用户输入的任何一个值不是数时都捕获ValueError 异常,并打印一条友好的错误消息。对你编写的程序进行测试:先输入两个数,再输入一些文本而不是数。

print("Give me tow numbers, and I'll plus then.")
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:
        first_number = int(first_number)
        second_number = int(second_number)
    except ValueError:
        print("\nPlease INPUT numnber.")
    else:
        answer = first_number + second_number
        print(f"The sum of {first_number} and {second_number} is {answer}.")

练习10-8:猫和狗 创建文件cats.txt和dogs.txt,在第一个文件中至少存储三只猫的名字,在第二个文件中至少存储三条狗的名字。编写一个程序,尝试读取这些文件,并将其内容打印到屏幕上。将这些代码放在一个try-except代码块中,以便在文件不存在时捕获FileNotFound 错误,并显示一条友好的消息。将任意一个文件移到另一个地方,并确认except 代码块中的代码将正确执行。

filenames = ['text_files/dogs.txt', 'cats.txt']
for filename in filenames:
    try:
        with open(filename) as file_object:
            contexts = file_object.read()
    except FileNotFoundError:
        print(f"Sorry, the file {filename} does not exsit.")
    else:
        print(contexts)

练习10-9:静默的猫和狗 修改你在练习10-8中编写的except 代码块,让程序在任意文件不存在时静默失败

filenames = ['text_files/dogs.txt', 'cats.txt']
for filename in filenames:
    try:
        with open(filename) as file_object:
            contexts = file_object.read()
    except FileNotFoundError:
#         print(f"Sorry, the file {filename} does not exsit.")
        pass
    else:
        print(contexts)

# function
def find_count_words(filename, line):
    try:
        with open(filename, encoding='utf-8') as file_object:
            contents = file_object.read()
    except FileNotFoundError:
#        pass
        print(f"Sorry, the file {filename} does not exist.")
    else:
        count  = contents.count(line)
        print(count)

# main
from  function.find_count_words import find_count_words
filename = 'text_files/完美世界.txt'
print(f"Enter 'q' to quit")
while True:
    line = input(f"请输入需要查找的句子,我将打印出此句出现的次数: ")
    if line == 'q':
        break
    with open(filename,encoding='utf-8') as file_object:
        contexts = file_object.read()
    find_count_words(filename, line)

5 存储数据

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

import json

numbers = [2, 3, 5, 6, 11, 13]
filename = 'data/numbers.json'
with open(filename, 'w') as file_object:
    json.dump(numbers, file_object)

import json

filename = 'data/numbers.json'
with open(filename, 'r') as file_object:
    numbers = json.load(file_object)
print(numbers)

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

5.2.1 保存用户生成的数据

import json
#
username = input("What is your name? ")
filename = 'data/username.json'
with open(filename, 'w') as file_object:
    json.dump(username,file_object)
    print(f"We'll remeber you when you come back,{username}")

5.2.2 读取用户生成的数据

filename = 'data/username.json'
with open(filename) as file_object:
    username = json.load(file_object)
    print(f"Welcome back,{username}!")

5.2.3 记住登录的用户

filename = 'data/username.json'
try:
    with open(filename, 'r') as file_object:
        username = json.load(file_object)
except FileNotFoundError:
    username = input("What is your name? ")
    with open(filename, 'w') as file_object:
        json.dump(username, file_object)
        print(f"We'll remeber you when you come back,{username}")
else:
    print(f"Welcome back, {username}!")

5.2.4 最终完成版

remember_me.

# function
def get_stored_username():
    """If the username is stored, it can be retrieved. """
    filename = 'data/username.json'
    try:
        with open(filename) as file_object:
            username = json.load(file_object)
    except FileNotFoundError:
        return None
    else:
        return username


def get_new_username():
    """Prompt user to enter username."""
    username = input("What is your name?")
    filename = 'data/username.json'
    with open(filename, 'w') as file_obejct:
        json.dump(username, file_obejct)
    return username


def greet_user():
    """ Greet the user and indicate their name. """
    username = get_stored_username()
    if username:
        print(f"Welcome back, {username}! ")
    else:
        username = get_new_username()
        print(f"we'll remember you when you come back, {username}! ")
# main
from function.greet_user import greet_user
greet_user()

5.3 练习题

import json
number = input("\n请输入一个你喜欢的数字: ")
filename = 'data/numbers.json'
with open(filename, 'w') as file_object:
    json.dump(number, file_object)

filename = 'data/numbers.json'
try:
    with open(filename, 'r') as file_object:
        number = json.load(file_object)
        print(f"Welcome back,Your love number is : {number}")
except FileNotFoundError:
    print(f"file does not exist.")