6.文件
在介绍文件和及其异常之前我们先介绍一下Python的标准库。
Python标准库是一组模块,我们安装Python都包含他。
示例:
from random import randint
numbers = randint(1, 6)
print(numbers)
'''生成1到6之间的随机数,包含1和6。'''
from random import choice
sb = ['xc', 'kx', 'zlx', 'tthxq']
print(choice(sb))
'''函数choice将列表作为参数并返回其中的随机一个元素。'''
6.1 从文件中读取数据
6.1.1 读取整个文件
示例(需要读取的文本文件):
示例(打开程序文件):
with open('file_reader') as zlx:
'''
使用函数open来返回一个表示文件的对象,
在这里返回表示文件file_reader的对象,
并把该对象赋给zlx供以后使用。
with关键字在不再需要访问后将其关闭。
'''
contents = zlx.read()
print(contents.rstrip())
6.1.2 关于文件路径
直接上示例:
with open('/Users/zh/Desktop/jiamei.txt') as zlx:
'''
通过使用绝对路径可以访问到计算机什么的任意路径的文件
如果不用这个的话,Python默认是读取python_work目录中的文件。
'''
contents = zlx.read()
print(contents.rstrip())
注意: 如果在文件路径中使用斜杠“/”, 将会应付错误,因为反斜杠用于对字符串中的字符进行转义。例如, 对于绝对路径"C:\path\to\file.txt", 其中\t 将会被解读为制表符。如果一定要用反斜杠, 可对路径中的每个反斜杠都进行转义, 如:"C:\\path\\to\\file.txt""C:\path\to\file.txt"。
6.1.3 逐行读取
直接上示例:
with open('file_reader') as zlx:
for line in zlx:
print(line.strip())
6.1.4 创建一个包含文件各行内容的列表
使用关键字with时,open()返回的文件对象只在with代码块内可用。
sb = 'file_reader'
with open(sb) as zlx:
lines = zlx.readlines()
'''
方法readlines从文件中读取每一行,
并将其存储在一个列表中。
'''
for line in lines:
print(line)
6.1.5 使用文件内容
将文件读取到内存中后, 就能以任何方式使用这些数据了。
示例:
sb = 'file_reader'
with open(sb) as zlx:
lines = zlx.readlines()
cn = ''
'''
把列表里的元素统统装到变量里面
'''
for line in lines:
cn += line.strip()
print(cn)
print(len(cn))
注意: 读取本文件时, Python将其中的所有文本都解读为字符串。如果读取的是数,并要将其作为数值使用,就不许使用函数int()将其转换为整数或者使用函数float()将其转变为浮点数。
6.1.6 包含一百万位的大型文件
示例:
sb = 'file_reader'
with open(sb) as zlx:
lines = zlx.readlines()
cn = ''
'''
把列表里的元素统统装到变量里面
'''
for line in lines:
cn += line.strip()
print(cn[:3])
'''显示前三个元素'''
print(len(cn))
6.1.7 圆周率值中包含你的生日吗
示例:
sb = 'file_reader'
with open(sb) as zlx:
lines = zlx.readlines()
cn = ''
'''
把列表里的元素统统装到变量里面
'''
for line in lines:
cn += line.strip()
while True:
birthday = input('Please enter your birthday:')
if birthday in cn:
print('np!')
else:
print('sb!')
6.2 写入文件
保存数据最简单的方法之一就是将其写入到文件中。通过将其输出写入文件,即便关闭包含程序输出的终端窗口, 这些输出依然纯在:可以在程序结束运行后查看这些输出,可以与别人分享输出文件,还可以编写程序来将这些输出读取到内存中并进行处理。
6.2.1 写入空文件
示例:
filename = 'file_reader'
with open(filename, 'w') as zlx:
zlx.write('I love programming.')
'''
在本例中,调用open时提供了两个实参。
第一个是要打开文件的名,第二个实参‘w’告诉Python,
要以写入模式打开这个文件。
打开文件时,可指定读取模式(‘r’)、写入模式('w')、附加模式('a')、读写模式('r+')。
如果忽略了模式参数,
Python将以默认的只读模式打开文件。
'''
注意: 如果要写入的文件不存在,函数open将会自动创建他。如果以写入模式(‘w’)打开文件时要小心,因为指定的文件已经纯在的话,Python将在返回文件对象前清空该文件的内容。
Python只能将字符串写入本文本文件。要将数值数据存储到文本文件中,必须要先使用函数str()将其转换为字符串格式。
6.2.2 写入多行
直接上示例:
filename = 'file_reader'
with open(filename, 'w') as zlx:
zlx.write('I love programming.')
zlx.write('\nI love creating new games.')
6.2.3 附加到文件
如果要给文件添加内容,而不是覆盖原有的内容,可以以附加模式打开文件。
示例:
filename = 'file_reader'
with open(filename, 'a') as zlx:
zlx.write('I love programming.')
zlx.write('\nI love creating new games.')
6.3 异常
Python使用称为异常的特殊对象来管理程序执行期间发生的错误。每当发生Python不知所措的错误时, 他都会创建一个异常对向。如果你编写了处理该异常的代码,程序将继续运行;如果未对异常进行处理,城程序将停止并显示traceback, 其中包含有关异常的报告。
6.3.1 处理ZeroDivisionError 异常
错误代码示例:
print(5/0)
错误提示(traceback):
黄色括号里的就是异常对象, Python无法按你的要求做时,就会创建这种对象。
6.3.2 使用 try-except 代码块
当你认为可能会发生错误的时候,可以编写一个try-except代码块来处理可能引发的异常。你让Python来尝试运行一些代码,并告诉他如果这些代码引发了指定的异常该怎么办。
示例:
try:
print(5/0)
except:
print("You can't divide by zero!")
6.3.3 使用异常避免崩溃
发生错误事,如果程序还有工作尚未完成,妥善地处理错误就尤为重要。这种情况经常会出现在要求用户提供输入的程序中;如果程序能够妥善地处理无效输入,就能再提示用户提供有效输入,而不至于崩溃。
下面来创建一个只执行除法运算的简单计算器:
print("Give me two nubers, and I'll divde them.")
print("Enter 'q' to quit")
'''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)
分母输入0后引发ZeroDivisionError异常。
6.3.4 else 代码块
直接上示例:
print("Give me two nubers, and I'll divde them.")
print("Enter 'q' to quit")
'''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)
'''else代码等try代码块执行代码成功后执行'''
6.3.5 处理FileNotFoundError 异常
使用文件时, 可能找不到文件: 查找的文件可能在其他的地方,文件名可能不正确,或者这个文件根本不存在。对于所有这些情况,都可以使用try-except代码以直观的方式来处理。
其使用方法跟之前的那个对象异常一样,比到框框买娄娄属于是。
示例:
filename = 'alice.txt'
try:
with open(filename, encoding = 'utf-8') as f:
contents = f.read()
'''
这里不一样的是给参数encoding指定了值,
在系统的编码与要读取的文件使用的编码不一致时必须这样做
'''
except:
print('Hello!')
6.3.6 分析文本
我们可以分析包含整本书的文本文件。
使用方法split(),他能根据一个字符串创建一个单词列表。
示例:
zlx = 'Hello the world!'
print(zlx.split())
6.3.7 使用多个文件
直接上示例:
def count_words(filename):
'''
计算多个文本中包含多少单词。
'''
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except:
print('hhhhhhhhhhhhhhhhhhhhhhhhhhh')
else:
words = contents.split()
num_words = len(words)
print(f"The file {filename} has about {num_words} words")
filenames = ['sb.txt', 'nb.txt', 'hjb.txt']
for fiename in filenames:
print(count_words(fiename))
6.3.8 静默失败
有时候,我们希望程序在发生异常时保持沉默。
示例:
def count_words(filename):
'''
计算多个文本中包含多少单词。
'''
try:
with open(filename, encoding='utf-8') as f:
contents = f.read()
except FileNotFoundError:
pass
else:
words = contents.split()
num_words = len(words)
print(f"The file {filename} has about {num_words} words")
filenames = ['file_reader', 'nb.txt', 'hjb.txt']
for fiename in filenames:
print(count_words(fiename))
6.4 存储数据
很多程序都要求用户输入某种信息,如让用户存储游戏首选项或提供要可视化的数据。不管关注点是什么, 程序都把用户提供的信息存储在列表和字典等数据结构中。用户关闭程序时,几乎总是要保存他们提供的信息。一种简单的方式是使用模块json来存储数据。
6.4.1 使用 json.dump()和 json.load()
示例:
import json
numbers = [2, 3, 5, 7, 11, 13]
filename = 'file_reader'
with open(filename, 'w') as f:
json.dump(numbers, f)
'''使用函数json.dump将数字列表numbers存储到f文件中'''
import json
filename = 'file_reader'
with open(filename) as f:
numbers = json.load(f)
'''函数json.load将列表读取到内存当中'''
print(numbers)
6.4.2 保存和读取用户生成的数据
使用 json 保存用户大生成的数据大有裨益,因为如果不以某种方式存储,用户的信息会在程序停止停止运行时丢失。
示例:
import json
usersb = input('hhhhhhhhhhhhhhhhhh:')
filename = 'file_reader'
with open(filename, 'w') as f:
json.dump(usersb, f)
print(usersb)
import json
filename = 'file_reader'
with open(filename) as f:
usersb = json.load(f)
print(usersb)
import json
filename = 'file_reader'
try:
with open(filename) as f:
usersb = json.load(f)
except:
print('nononononono')
usersb = input(':')
with open(filename, 'w') as f:
json.dump(usersb, f)
print(usersb)
else:
print(usersb)
'''
如果以前存储了数字,就加载他。
否则,提示用户输入数字并存储他
'''
6.4.3 重构
当遇到代码能够正确运行,但通过将其划分为一系列完成具体工作的函数,还可以改进。这样的过程称为重构。重构让代码更加清晰、更容易理解、更容易扩展。
要重构remember_me.py, 可将其大部分逻辑放到一个或多个函数中。remember_me.py的重点是问候用户,因此将其所有代码都放到一个名为greet_user()的函数中。
示例:
import json
def get_stored_username():
'''如果存储了用户名,就获取他'''
filename = 'file_reader'
try:
with open(filename) as f:
username = json.load(f)
except:
return None
else:
return username
def get_new_username():
'''提示用户输入名称'''
username = input("What is your name?")
filename = 'file_reader'
with open(filename, 'w') as f:
json.dump(username, f)
return username
def greet_user():
'''问候用户,并指出其名称'''
username = get_stored_username()
if username:
print(username)
else:
username = get_new_username()
print(username)
greet_user()
#细化细化再细化,切记。