Python学习笔记8—文件和异常

一、从文件中读取数据

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

1、读取整个文件

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

注:

  • 以任何方式使用文件都要先打开文件才能访问它。函数open()接受一个参数,要打开的文件的名称,Python在当前执行的文件所在的目录中查找指定的文件。查找后返回一个对象。
  • 关键字with在不再需要访问文件后将其关闭。当然,也可以分别调用open() close()函数来打开和关闭文件,但是,① 如果程序存在bug时,导致close()语句未执行,文件将不会关闭,导致数据受损或丢失;②过早调用close(),可能还需要使用文件时它已经关闭了,这会导致错误。所以,并非在任何时候都能轻松确定关闭文件的恰当时机,调用关键字with,你只管打开文件,并在需要时使用它,Python自会在合适的时候自动将其关闭。
  • rstrip()用于删除文件末尾的空字符串,因为read()达到文件末尾时返回一个空字符串,最终输出会多一行空行。

2、文件路径

①相对路径

在Linux和OS X系统中

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

在Windows系统中

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

② 绝对路径

在相对路径行不通时,可以采用绝对路径。绝对路径通常比相对路径长更长,因此将其存储在也变量中,再将变量传递给open()会有所帮助。
在Linux和OS X系统中

file_path = 'home/other_files/text_files/filename.txt'
with open(file_path) as file_object:

在Windows系统中

file_path = 'C:\Users\other_files\text_files\filename.txt'
with open(file_path) as file_object:

就目前而言,最简单的做法是:要么将数据文件存储在程序文件所在的目录,要么将其存储在程序文件所在目录下的一个文件夹中。

2、逐行读取

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

注:

  • 将文件名存储在变量filename是个不错的做法。
  • 因为输出会多了空白行,每行末尾都有一个看不见的换行符,而print语句也会加上一个换行符,为消除多余的空白行,调用函数rstrip()

4、创建一个包含文件各行内容的列表,使用文件的内容

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

filename = 'digits.txt'

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

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

 print(pi_string)

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

二、写入文件

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

注:

  • 调用open()需要提供两个实参,第一个是要打开的文件的名称,第二个是读写模式,如:读取模式 'r' 、写入模式 'w' 、附加模式 'a' 、读取和写入模式 'r+'。若省略则默认是只读模式。
  • Python只能将字符串写入文本文件。要将数值数据存储到文本文件中国,必须先使用函数str()将其转换为字符串格式。
  • 函数wirte()不会在你写入的文本末尾添加换行符,若要换行需自己手动添加\n
  • 如果要写入的文件不存在,函数open()将自动创建它。注意,以写入 'w' 模式打开文件时要小心,如果指定的文件已经存在,Python将在返回文件对象前清空该文件。以附加 'a' 模式的则不会清空文件内容。

三、异常

Python使用被称为异常的特殊对象来管理程序执行期间发生的错误,每当发生让Python不知所措的错误时,它都会创建一个异常对象。如果你编写了处理该异常的代码,程序将继续运行,如果你未对异常进行处理,程序将停止,并显示一个traceback,其中包含有关异常的报告。
异常是使用try-expect代码块处理的。try-expect代码块让Python执行指定的操作,同时告诉Python发生异常时要怎么处理。使用了try-expect代码块时,即使出现异常,程序也将继续运行:显示你编写的友好的错误信息,而不是令用户迷惑的traceback。

1、使用try-expect-else代码块

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("\nSecond number: ")
    if second_number == 'q':
        break
    try:
        answer = int(first_number) / int(second_number)
    expect ZeroDivisionError:
        print("You can't divide by 0!")
    else:
        print(answer)

try-expect-else代码块的工作原理如下:Python尝试执行try代码块中的代码,只有可能引发异常的代码才需要放在try语句中。当发生了expect中的错误时执行expect中的代码,否则,执行else中的代码,else中是存放依赖于try代码块成功执行的代码。

2、失败时一声不吭

try:
    --snip--
expect:
    pass
else:
    --snip--

注:pass充当了占位符,提醒你在程序的某个地方什么都没有做,而且以后也许要在这里做些什么。

四、存储数据

模块json可将Python数据结构转储到文件中中,并在程序再次运行时加载该文件中的数据,还可以使用json在Python程序之间分享数据。更重要的是,JSON数据格式并非Python专有的,这让i能够将以JSON格式存储的数据与使用其他编程语言的人分享。

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

number_writer.py

import json

numbers = [1,2,3,4,5]

filename = 'numbers.json'
with open(filename,'w') as f_obj:
    json.dump(numbers,f_obj)

注:

  • 先导入json模块
  • json.dump()接受两个实参:要存储的数据以及可用于存储数据的文件对象。
    number_reader.py
import json

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

print(numbers)

注:

  • 先导入json模块
  • json.load()接受一个实参:要加载的数据对象。

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

remember_me.py

import json

# 如果以前存储了用户名,就加载它
# 否则,就提示用户输入用户名并存储它
filename = 'username.json'
try:
    with open(filename) as f_obj:
        username = json.load(f_obj)
expect FileNotFoundError:
    username = input("What is your name? ")
     with open(filename,'w') as f_obj:
        json.dump(username,f_obj)
        print("We'll remember you when you come back, " + username + "!")
else:
print('Welcome back, " + username + "!")

3、重构

将代码划分为一系列完成具体工作的函数,称为重构。重构让代码更清晰、更易于理解、更容易扩展。
remmenber_me.py

import json

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

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

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

greet_user()

你可能感兴趣的:(Python学习笔记8—文件和异常)