10.文件和异常

文件和异常

从文件中读取数据

要使用文本文件中的信息,首先需要将信息读取到内存中

读取整个文件

pi_digits.txt

3.1415926535
   8979323846
   2643383279

file_reader.py

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

函数open()返回一个表示文件的对象

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

也可以调用open()和close()来打开和关闭文件,但是如果程序有Bug,导致close()语句未执行,文件将不会关闭,可能会导致数据丢失或受损。如果过早调用close(),会发现需要使用文件时它已经关闭,会导致更多错误。

方法read()读取这个文件的全部内容,并将其作为一个长长的字符串存储在变量contents中;到达文件末尾时返回一个空字符串,显示出来为一个空行,可用restrip()方法删除

文件路径

将'pi_digits.txt'传给open()时,Python将在当前执行的文件所在目录中查找文件

使用相对文件路径打开文件:Python到相对于当前运行的程序所在目录进行查找

with open('text_files\filename.txt') as file_object:

使用绝对路径:可读取系统任何地方的文件

file_path = 'C:\Users\19405\Desktop\filename.txt'

with open(file_path ) as file_object:

绝对路径通常比相对路径更长,因此将其存储在一个变量中,再将该变量传递给open()会有所帮助

逐行读取

file_path = 'pi_digits.txt'
with open(file_path) as file_object:
    for line in file_object:
        print(line)

文件中,每一行的末尾有一个看不见的换行符,print()语句也会加一个换行符,因此输出的每行末尾会有两个换行符:一个来自文件,一个来自print()

消除多余空白行:

print(line.rstrip())

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

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

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

for line in lines:
    print(line.rstrip())

方法readlines()从文件中读取每一行,并将其存储再一个列表中

使用文件的内容

filename = 'pi_digits.txt'

with open(filename) as file_object:
    lines = file_object.readlines()

pi_string = ''
for line in lines:
    pi_string += line.strip()

print(pi_string)
print(len(pi_string))

读取文本文件时,Python将其中所有文本都解读为字符串;如果读取的是数字,要将其作为数值使用,就必须使用函数int()或者float()将其转换为整数或浮点数

包含一百万位的大型文件

filename = 'pi_million_digits.txt'

--snip--

print(pi_string[:52] + '...')
print(len(pi_string))

圆周率中包含你的生日吗

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("No")

写入文件

保存数据最简单的方式之一

写入空文件

filename = 'programming.txt'

with open(filename, 'w') as file_object:
    file_object.write("I love programming.")

open()的第二个实参:

'r':读取模式

'w':写入模式:文件不存在,则自动创建;若文件已存在,则清空该文件

'a':附加模式

'r+':读取和写入模式

Python只能将字符串写入文本文件

写入多行

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

filename = 'programming.txt'

with open(filename, 'w') as file_object:
    file_object.write("I love programming.\n")
    file_object.write("I love creating new games.\n")

附加到文件

给文件添加内容,而不是覆盖原有的内容

附加模式

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 creating new games.\n")

异常

Python使用被称为异常的特殊对象来管理程序执行期间发生的错误

每当发生错误时,都会创建一个异常对象

异常是使用try-except代码块处理的。使用了该模块,即便出现异常,程序也将继续运行

处理ZeroDivisionError异常

print(5/0)

程序运行失败,并返回一个Traceback,创建了一个ZeroDivisionError对象

使用try-except代码块

编写一个try-except代码块来处理可能发生的异常

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

如果try代码块中的代码运行没有问题,将跳过except代码块;

如果try代码块的代码导致了错误,Python将查找这样的expect代码块,并运行其中的代码,即其中指定的错误与引发的错误相同

使用异常避免崩溃

经常用于要求用户提供输入的程序中

如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃

division.py

print("Give me two number, and I will divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number: ")
    if first_number == 'q':
        break
    second_number = input("\nSecond number: ")
    if second_number == 'q':
        break
    answer = int(first_number) / int(second_number)
    print(answer)

second_number输入为0会导致程序崩溃

else代码块

将可能引发错误地代码放在try-except代码块中,可提高这个程序地低于错误地能力

print("Give me two number, and I will divide them.")
print("Enter 'q' to quit.")

while True:
    first_number = input("\nFirst number: ")
    if first_number == 'q':
        break
    second_number = input("\nSecond 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)

依赖于try代码块成功执行地代码都放在else代码块中

处理FileNotFoundError异常

找不到文件

alice.py

filename = 'alice.txt'

try:
    with open(filename) as f_obj:
        contents = f_obj.read()
except FileNotFoundError:
    print("Sorry, the file " + filename + " dose not exist.")

分析文本

计算一个文本中包含多少个单词

split()方法:根据一个字符串创建一个单词列表;以空格为分隔符拆分字符串

def count_words(filename):
    """计算一个文件大致包含多少单词"""

    try:
        with open(filename) as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
        print("Sorry, the file " + filename + " dose not exist.")
    else:
        # 计算文件大致包含多少个单词
        words = contents.split()
        num_words = len(words)
        print("The file " + filename + " has about " + str(num_words) + "words.")

filename = 'alice.txt'
count_words(filename)

失败时一声不吭

在expect代码块中明确告诉Python什么都不要做

pass语句:让Python什么都不做

except FileNotFoundError:
    pass

不会出现traceback,也不会有任何输出

决定报告哪些错误

凭借经验判断该在程序地什么地方包含异常处理块,以及出现错误时该向用户提供多少相关信息

存储数据

使用模块josn来存储数据

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

json.dump()存储数据列表

import json

numbers = [2, 3, 5, 7, 11, 13]
filename = 'numbers.json'
with open(filename, 'w') as f_obj:
    json.dump(numbers, f_obj)

json.load()将列表读取到内存中

import json

filename = 'numbers.json'
with open(filename) as f_obj:
    numbers = json.load(f_obj)

print(numbers)

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

import json

#如果以前存储了用户名,就加载它;否则,就提示用户输入用户名并存储它
filename = 'name.json'
try:
    with open(filename) as f_obj:
        username = json.load(f_obj)
except FileNotFoundError:
    username = input("What's your name: ")
    with open(filename, 'w') as f_obj:
        json.dump(username, f_obj)
        print("Hello, " + username)
else:
    print("Welcome back, " + str(username) + "!")

重构

重构:将代码划分为一系列完成具体工作的函数

import json

def get_stored_username():
    """如果存储了用户名,就获取它"""
    filename = 'name.json'
    try:
        with open(filename) as f_obj:
            username = json.load(f_obj)
    except FileNotFoundError:
        return None
    else:
        return username

def get_new_username():
    """提示用户输入用户名"""
    username = input("What's your name: ")
    filename = 'name.json'
    with open(filename, 'w') as f_obj:
        json.dump(username, f_obj)
    return username

def greet_user():
    """问候用户,并指出其名字"""
    username = get_stored_username()
    if username:
        print("Welcome back, " + username + "!")
    else:
        username = get_new_username()
        print("We'll remeber you when you come back, " + username + "!")

greet_user()

 

posted @ 2021-11-25 17:11  KYZH  阅读(78)  评论(0)    收藏  举报