欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python-10-文件和异常-学习笔记

程序员文章站 2022-09-13 22:42:36
1.从文件中读取数据读取整个文件pi_digits.txt的内容3.1415926535 8979323846 2643383279file_reader.py文件内容open(‘pi_digits.txt’):返回一个表示文件pi_digits.txt的对象关键字 with:在不再需要访问文件后将其关闭,让Python去确定:使用者只管打开文件,并在需要的时候使用,Python会在适合的时候自动将其关闭。本程序中使用了open(),却没有调用close(),人工确定是否打开和关闭...

1.从文件中读取数据

读取整个文件

pi_digits.txt的内容

3.1415926535 
 8979323846 
 2643383279

file_reader.py文件内容
open(‘pi_digits.txt’):返回一个表示文件pi_digits.txt的对象
关键字 with:在不再需要访问文件后将其关闭,让Python去确定:使用者只管打开文件,并在需要的时候使用,Python会在适合的时候自动将其关闭。
本程序中使用了open(),却没有调用close(),
人工确定是否打开和关闭文件:调用open()和close(),但这种操作很容易出问题。

'''
open('pi_digits.txt'):返回一个表示文件pi_digits.txt的对象
关键字with:在不再需要访问文件后将其关闭
'''
# 版本1
with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents)

#版本2
#输出结果和版本1相同,就是删除了末尾空行
with open('pi_digits.txt') as file_object:
    contents = file_object.read()
    print(contents.rstrip())
    #要删除末尾的空行,可在print语句中使用rstrip()

文件路径

路径 理解
相对路径 该位置是相对于当前运行的程序(即.py程序文件)所在目录的 ,一般是在同一个目录下的子目录中寻找
绝对路径 文件在计算机中的准确位置,提供的是完整的路径,相对路径行不通的时候,使用绝对路径

注意:在Windows系统中,在文件路径中使用的反斜杠(/),与Linux和OS X系统是不一样的。

举例说明
假设:当程序文件file_reader.py存储在文件夹python_work中,在python_work中,有一个名为text_files的文件夹里存放一个filename.txt。
需要在程序文件中打开filename.txt时使用以下代码:

#方法1:采用相对路径
with open(r"text_files\filename.txt") as file_object:
'''
由于反斜杠\在python中被视为转义标记,为在Windows中确保不出错,应以原始字符串的方式指定路径,即在开头的引号前加上r
'''
    contents = file_object.read()
    print(contents.rstrip())

#方法2:采用绝对路径
file_path =r'G:\python_work\text_files\filename.txt'
with open(file_path) as file_object:
#----snip----

逐行读取

filename = 'pi_digits.txt'

with open(filename) as file_object:
    for line in file_object:
        print(line)

运行结果:
python-10-文件和异常-学习笔记
打印每一行时,多了些空白行,其原因是在这个文件中,每行的末尾都有一个看不见的换行符,而print语句也会加上一个换行符。
两个换行符:一个来自文件,一个来自print语句。
要消除多余的空白行,还是采用在print语句中使用rstrip()

#----snip----
    for line in file_object:
        print(line.rstrip())

运行结果:
python-10-文件和异常-学习笔记

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

filename = 'pi_digits.txt'
with open(filename) as file_object:
    lines = file_object.readlines()
    # readlines()从文件中读取每一行,并将其存储在一个列表lines中
    
# 采用for循环打印lines中的各行
for line in lines:
    print(line.rstrip())

使用文件的内容

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

# 创建一个变量pi_string用于存储圆周率的值    
pi_string = ''

# 采用一个循环将各行都加入pi_string,并删除每行末尾的换行符
for line in lines:
    pi_string += line.rstrip()
    
# 打印字符串及其长度
print(pi_string)
print(len(pi_string))

python-10-文件和异常-学习笔记

#----snip----表示相同代码

#----snip----
#将rstrip()改为strip(),不仅删除空行,还删除空格,运行结果见下
for line in lines:
    pi_string += line.strip()
#----snip----

python-10-文件和异常-学习笔记
Python使使int()使float()\color{red}{注:读取文本时,Python将其中所有文本都解读为字符串,如果读取的是数字,并要将其作为数值使用,就必须使用函数int()将其转换为整数,或使用函数float()将其转换为浮点数。}

包含一百万位的大型文件

filename = 'pi_million_digits.txt'

#----snip----

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

python-10-文件和异常-学习笔记
Python\color{red}{注:对于用户可处理的数据量,Python没有任何限制,只要系统内存足够多,想处理多少数据都可以。}

圆周率中是否包含你的生日

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

# 创建一个变量pi_string用于存储圆周率的值
pi_string = ''
for line in lines:
    pi_string += line.strip()

# 提示用户输入生日
birthday = input('Enter your birthday, in the form mmddyy: ')

# 用if语句进行判断
if birthday in pi_string:
    print('Your birthday appears in the first million digits of pi!')
else:
    print('Your birthday does not appears in the first million digits of pi')


运行结果
python-10-文件和异常-学习笔记

2、写入文件

写入空文件

相关说明:
调用open()时,可指定读取模式(‘r’)、写入模式(‘w’)、附加模式(‘a’)或能够读取和写入的模式(‘r+’)。
未指定时,Python默认只读模式打开文件。

1open()\color{red}{注 1:如果要写入的文件不存在,函数open()将自动创建它。}
2(w)Python\color{red}{注2 : 如果以写入模式('w')打开文件时要特别注意,若指定的文件已存在,Python在返回文件对象前清空该文件。}
3Python使str()\color{red}{注 3: Python只能将字符串写入文本文件,要想将数值数据存储到文本文件中,必须先使用函数str()将其转换为字符串格式。}

filename = 'programming.txt'

''' 
调用open()时提供了两个实参,
第一个是要打开的文件的名称,
第二个实参('w')是告诉Python,要以写入的模式打开该文件。
'''
with open(filename, 'w') as file_object:
    file_object.write('I love programming.')

写入多行

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')
    #如果write语句中不加\n换行符,则写入的语句是在同一行的

附加到文件

如果是给文件添加内容,而不是覆盖原有的内容时,以附加模式打开文件。如果此时指定的文件不存在,Python将创建一个空文件。

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 app that can run in a browser.\n')

python-10-文件和异常-学习笔记
练习.填写访客名单

filename = 'guest.txt'
while True:
    keep_running = input("有访客到来吗?(y/n):")
    if keep_running == 'n':
        break
    s = input('请输入您的姓名:')

    with open(filename, 'a') as file_object:
        file_object.write(s+'\n')
    print(s + "欢迎你的到来!")

3. 异常

处理ZeroDivisionError异常

举例:当一个数字除以0的时候会发生异常错误

使用try-except代码块

将导致错误的代码行放在一个try代码块中,如果try中的代码块运行起来没有问题,Python将跳过except代码块;如果try代码块中的代码导致了错误,Python将查找except代码块,并运行其中的代码,见例1。
如果try-except代码块后面还有其他代码,程序将接着运行,因为已经告诉了Python如何处理这种错误,见例2。

使用try-except-else代码块

在例2中,try中的代码块只包含可能导致错误的代码。依赖于try代码块成功执行的代码都放在else代码块中。

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


# 例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('\nSecond number:')
    if second_number == 'q':
        break
        
    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("You can't divide by zero!")
    #使用else-代码块来打印结果
    else:    
        print(answer)

处理FileNotFoundError异常

当尝试读取一个不存在的文件时,会引发FileNotFoundError异常

filename = 'alice.txt'

with open(filename) as f_obj:
    contents = f_obj.read()

异常如下

Traceback (most recent call last):
  File "G:/File_test/alice.py", line 3, in <module>
    with open(filename) as f_obj:
FileNotFoundError: [Errno 2] No such file or directory: 'alice.txt'

在上述示例中,这个错误是open()导致的,因此要处理这个错误,必须将try语句放在包含open()的代码行之前:

filename = 'alice.txt'
try:
    with open(filename) as f_obj:
        contents = f_obj.read()
except FileNotFoundError:
    msg = 'Sorry, the file ' + filename + ' does not exist.'
    print(msg)

Sorry, the file alice.txt does not exist.

分析文本

本节中使用的文本来自项目Gutenberg(http://gutenberg.org/)

title = 'Alice in Wonderland'
print(title.split())

方法split()以空格为分隔符将字符串拆成多个部分,并将这些部分都存储到一个列表中。

['Alice', 'in', 'Wonderland']

首先将alice.txt文件存放到和alice.py同一目录下,然后执行以下代码

filename = 'alice.txt'

try:
    with open(filename, encoding='utf-8') as f_obj:
    #未加encoding='utf-8'时会出现异常
    
# ————snip————

else:
	# 计算文件大致包含多少个单词
    word = contents.split()
    num_words = len(word)
    print('The file ' + filename + ' has about ' + str(num_words) + ' words.')

未加encoding='utf-8’时出现以下异常时,

Traceback (most recent call last):
  File "G:/File_test/alice.py", line 5, in <module>
    contents = f_obj.read()
UnicodeDecodeError: 'gbk' codec can't decode byte 0x9d in position 1596: illegal multibyte sequence

参考:
(https://blog.csdn.net/shijing_0214/article/details/51971734)
(https://blog.csdn.net/The_Time_Runner/article/details/92775720)

#正确运行结果
The file alice.txt has about 29608 words.

使用多个文件

代码与上面基本相同,仅将这些代码移到count_words()中,并增加了缩进量。

# 版本1.使用一个文件
def count_words(filename):
    '''计算一个文件大概包含多少个单词'''
    try:
        with open(filename, encoding='utf-8') as f_obj:
            contents = f_obj.read()
    except FileNotFoundError:
        msg = 'Sorry, the file ' + filename + ' does not exist.'
        print(msg)
    else:
        # 计算文件大致包含多少个单词
        word = contents.split()
        num_words = len(word)
        print('The file ' + filename + ' has about ' + str(num_words) + ' words.')

filename = 'alice.txt'
count_words(filename)


# 版本2.使用多个文件
def count_words(filename):
# ————snip————

#其中,dream.txt在word_count.py所在的目录中是没有的
filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
    count_words(filename)

# 版本1.运行结果
The file alice.txt has about 29608 words.

# 版本2.运行结果
The file alice.txt has about 29608 words.
Sorry, the file dream.txt does not exist.
The file siddhartha.txt has about 42166 words.
The file moby_dick.txt has about 215829 words.
The file little_women.txt has about 5594 words.
def count_words(filename):
# ————snip————

filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
    count_words(filename)

失败时一声不吭

当希望程序在发生异常时一声不吭,就像什么都没有发生一样继续运行,采用在try-except-else代码块中使用pass语句。

def count_words(filename):
    '''计算一个文件大概包含多少个单词'''
    try:
# ————snip————
    except FileNotFoundError:
    	pass
    else:
# ————snip————


filenames = ['alice.txt', 'dream.txt', 'siddhartha.txt', 'moby_dick.txt', 'little_women.txt']
for filename in filenames:
    count_words(filename)

# 运行结果
The file alice.txt has about 29608 words.
The file siddhartha.txt has about 42166 words.
The file moby_dick.txt has about 215829 words.
The file little_women.txt has about 5594 words.

决定报告哪些错误

自行动手练习——之后再补

4. 存储数据

使用模块 json 来存储数据

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

  1. 第一个程序使用json.dump() 来存储这组数字,第二个程序将使用 json.load()。
  2. json.dump() 接受两个实参:要存储的数据,以及可用于存储数据的文件对象。
  3. json.load()加载存储在numbers.json中的信息,并将其存储到变量numbers中。
#number_writer.py文件
import json

numbers = [2, 3, 5, 7, 11, 13]

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

#number_reader.py文件
#使用json.load()将列表numbers读取到内存中
import json
filename = 'numbers.json'

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

print(numbers)

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

再次说明:变量filename表示的并非实际文件,它只是一个让Python知道到哪里去查找文件的字符串,因此可以轻松的将’username.json’替换为要使用的另一个文件的名称。

# remember_me.py文件
import json

username = input('What is your name?\n')

filename = 'username.json'
with open(filename, 'w') as f_obj:
    json.dump(username, f_obj)
    print("We'll remember you when you come back, " + username + "!")

# greet_user.py文件
import json

filename = 'username.json'

with open(filename) as f_obj:
    username = json.load(f_obj)
    print("Welcome back, " + username +"!")

# remember_me.py文件运行结果
What is your name?
Alice
We'll remember you when you come back, Alice!

# greet_user.py文件运行结果
Welcome back, Alice!

尝试将remember_me.py和greet_user.py合并到一个程序(remember_me.py)中

import json
'''
如果以前存储了用户名,就加载它
否则,就提示用户输入用户名并存储它
'''
filename = 'username.json'
try:
    with open(filename) as f_obj:
        username = json.load(f_obj)
except FileNotFoundError:
    username = input('What is your name?\n')
    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 + "!")

重构

import json

def greet_user():
    '''问候用户,并指出其名字'''
    try:
        with open(filename) as f_obj:
            username = json.load(f_obj)
    except FileNotFoundError:
        username = input('What is your name?\n')
        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 + "!")
        
greet_user()

重构greet_user()

import json

def get_stored_username():
    ''' 如果存储了用户名,就获取它'''
    filename = 'username.json'
    try:
        with open(filename) as f_obj:
            username = json.load(f_obj)
    except FileNotFoundError:
        return None
    else:
        return username
        
#新增一个函数greet_user()
def greet_user():
    '''问候用户,并指出其名字'''
    username = get_stored_username()

    if username:
        print("Welcome back, " + username + "!")
    else:
        username = input('What is your name?\n')
        filename = 'username.json'
        with open(filename, 'w') as f_obj:
            json.dump(username, f_obj)
            print("We'll remember you when you come back, " + username + "!")

greet_user()

继续优化上叙代码,将greet_user()中的另一个代码块提取出来:将没有存储用户名时,提示用户输入的代码放在一个独立的函数中:

import json


def get_stored_username():
    ''' 如果存储了用户名,就获取它'''
#————snip————


def get_new_username():
    '''提示用户输入用户名'''
    username = input('What is your name?\n')
    filename = 'username.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 remember you when you come back, " + username + "!")


greet_user()

本文地址:https://blog.csdn.net/sinat_36183354/article/details/107119853