珠海电商网站建设,药品网站 icp,帝国cms 网站地址设置,我想开一家网店怎么开文件和异常 
至此#xff0c;已经掌握了编写组织有序而易于使用的程序所需的基本技能#xff0c;该考虑让程序目标更明确、用途更大了。 
本章#xff0c;将学习文件处理#xff0c;它能让程序快速分析大量的数据#xff0c;也将学习错误处理#xff0c;避免程序在面对意…文件和异常 
至此已经掌握了编写组织有序而易于使用的程序所需的基本技能该考虑让程序目标更明确、用途更大了。 
本章将学习文件处理它能让程序快速分析大量的数据也将学习错误处理避免程序在面对意外时崩溃将学习异常它们时python创建的特殊对象用于管理程序运行时出现的错误还将学习json 模块它让你能够保存用户数据以免在程序停止运行后丢失。 
1、从文件中读取数据 
文本文件可以存储很多数据要使用文本文件中的信息首先需要将信息读取到内存中为此你可以一次性读取文件的全部内容也可以每一次一行的方式逐步读取。 
1.1、读取整个文件 
要读取整个文件只需将整个文件名读取到内存即可 
首先在程序所在文件目录创建一个名为pi_diigits.txt 的文本文件里面可以输入任何内容我们输入了圆周率并每隔10 个数字分行书写再创建一个名为file_reader.py 的文件下面我们将在这个程序中读取pi_digits.txt 中的信息并显示到屏幕上 
# pi_digits.txt
3.14159263589793238462643383279# file_reader.py
with open(pi_digits.txt) as file_object:contents  file_object.read()print(contents.rstrip())    # 打印出来的信息比原文本信息多了一个空行为此使用rstrip方法将其去掉
-----------
3.14159263589793238462643383279在这个程序中我们使用open函数来打开文件open函数有很多参数这里我们只需知道前两个即可第一个为要传入的文件名第二个为文件的打开模式python会在程序所在的目录去寻找pi_digits.txt 文件所以首先需要将指定文件放入到程序所在目录。 
打开文件后返回一个文件对象在这里我们将返回的文件对象命名为file_object第二行使用read方法这个文件全部内容并将其作为一个长字符串存储到变量contents 中再打印。 
事实上文件打开就需要关闭为此我们可以调用close函数关闭文件但有时如果程序存在bug导致clos语句未执行文件将不会关闭有可能导致数据丢失或受损所以在这里我们使用了关键字with它能在适当时机自动关闭文件让python自己去判断处理你只管打开文件并在需要时使用它。 
1.2、文件路径 
在给open函数传入参数时有时文件并不在程序文件所在目录比如程序所在的文件夹为python_work 而在文件夹python_work 中有一个名为text_files 的文件夹我们要打开text_files 目录下的filename.txt 文件如果我们只传入python_work\filename.txt 并不能找到因为python之会在python_work 中与程序文件同一个目录的文件中找为此我们需要提供文件路径让python到系统特定位置自己查找 
相对路径 
相对路径指的是该位置相对于当前运行的程序所在的目录下的某个文件夹中 
# 这是windows 系统中的方式OS X中使用斜杠/
with open(text_files\filename.txt) as file_object:绝对路径 
绝对路径指的是文件的精确位置无论文件在电脑哪个磁盘的哪个文件夹中 
# 这是windows 系统中的方式书上使用的是一个反斜杠经测试为两个 
file_path  C:\\Users\\hj\Desktop\\Deskto Folder\\new words.txt
with open(file_path) as file_object:# 这是OS X 系统方式为测试
file_path  /home/ehmatthes/other_files/text_files/fillname.txt1.3、逐行读取 
读取文件时常需要检查其中的每一行可能要在文件中查找特定信息或者要以某种方式修改文件中的文本要以每次一行的方式检查文件可以对文件对象使用for循环 
filename  pi_digits.txt
with open(filename) as file_object:for line in file_object: # 对文本对象执行循环遍历文件中的每一行print(line.rstrip())  # 打印每一行会对出空白行因此需要去掉
-----------
3.141592635897932384626433832791.4、创建一个包含文件各行内容的列表 
使用with 关键字open返回的文件对象只能在with 代码块内使用要在代码块外使用可以将文件各行存储到一个列表中你可以立即处理也可以推迟处理。 下面将with 代码块中的pi_digits.txt 文件各行内容存储到一个列表中再在外面使用 
filename  pi_digits.txtwith open(filename) as file_object:lines  file_object.readlines() # readlines() 方法可以从文件中读取每一行并将其存储到一个列表中linesfor line in lines:        # 遍历列表linesprint(line.rstrip())1.5、使用文件的内容 
将文件读取到内存后就可以以任何方式使用这些数据了下面以简单的方式使用圆周率创建一个字符串它包含文件中存储的所有数字且没有空格 
filename  pi_digits.txt
with open(filename) as file_object:lines  file_object.readlines()pi_string        # 创建一个变量用于存储文件中的内容
for line in lines:pi_string  lines.strip()  # 将读取的内容添加到pi_string 中print(pi_string)
print(len(pi_string))     # 打印其长度
-------------
3.14159263589793238462643383279
31读取文本文件时python将所有的文本都解读为字符串如果读取的是数字并要将其作为数值使用必须使用函数 int将其转换为整数或float将其转换为浮点数。 
1.6、读取一个包含百万位的大型文件 
前面我们都是读取一个只有三行的文本文件但这些代码示例也可以处理大得多的文件python没有任何限制只要有足够内存。 
如果有个文本文件包含了精确到小数点后1000000位的圆周率也可以使用前面的方式读取这里只打印小数点后50位 
filename  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(pi_string[:52]  ....)      # 打印小数点后50位
print(len(pi_string))
-------------
3.14159265358979323846264338327950288419716939937510....
10000021.7、检查文件中是否包含你所需的信息 
如检查520这个数字是否包含在百万级的圆周率中 
filename  pi_million_digits.txt
with open(filename) as file_object:lines  file_object.readlines()pi_string  
for line in lines:pi_string  line.strip()nums  input(Enter a num: )
if nums in pi_string:print(This num in pi_string.)
else:print(This num not in pi_string.)
----------
Enter a num: 520
This num in  pi_string.练习 创建一个文本文件名为learning_python.txt并将其存储到程序所在目录内容随意将各行存储到一个列表中再在with 代码块外打印它们 
with open(learning_python.txt) as file_object:lines  file_object.readlines()for line in lines:print(line.rstrip())
-------
In Python you can learned数据类型字符串、整型、浮点型、布尔型
In Python you can learned列表、元组、字典
In Python you can learnedif语句、while循环
In Python you can learned函数
In Python you can learned类、模块
In Python you can learned文件和错误异常
In Python you can learned用户输入将文件中的Python 替换成C可使用replcae‘old’, ‘new’方法 
with open(learning_python.txt) as file_object:lines  file_object.readlines()for line in lines:line  line.rstrip()print(line.replace(Python, C))           # replace()方法有2个参数第1个为要替换的元素第2个为替换的元素
-------------
In C you can learned数据类型字符串、整型、浮点型、布尔型
In C you can learned列表、元组、字典
In C you can learnedif语句、while循环
In C you can learned函数
In C you can learned类、模块
In C you can learned文件和错误异常
In C you can learned用户输入2、写入文件 
要想写入文件可以对文件对象使用write方法 
文件打开模式open函数它有2个实参第一个为要打开的文件名称第二个为打开模式如果不传入第二个实参python默认只读打开文件第二个实参可选以下模式 
打开模式执行操作‘r’以只读方式打开文件默认‘w’以写入方式打开会覆盖原有文件‘x’如果文件存在打开引发异常‘a’以写入方式打开若文件存在则在末尾追加写入‘b’以二进制模式打开‘t’以文本模式打开默认‘’可读写模式可添加到其他模式中使用‘U’通用换行符支持
2.1、写入空文件 
要将文本写入文件在调用open函数时传入第二个实参告诉python你要写入打开的文件模式再利用文件对象的一些方法对文件进行修改 
文件对象方法执行操作close关闭文件readsize读取size个字符若未指定size或为负则读取所有字符readlinesize读取整行定义size则返回一行的size个字节readlinessize读取文件的每一行并将其存储到一个列表中writestr将字符串str写入文件writelinesseq写入字符串序列列表、元组等tell返回文件当前位置seekoffset[, whence]设置文件当前位置,f.seek(0, 0/1/2)0代表起始位置1代表当前位置2代表文件末尾
filename  C:\\Users\\hj\\Desktop\\test\\hello.txt # 在这个路径创建一个hello.txt的文本文件with open(filename, w) as f:  # 以写入模式打开文件如果文件不存在open函数自动创建它f.write(hello word!)  # 如果要写入的是数值应先用str将其转换 
2.2、写入多行 
write方法不会在你写入的文本末尾添加换行符因此需要在末尾添加换行符 
filename  C:\\Users\\hj\\Desktop\\test\\hello.txt
with open(filename, w) as f:f.write(hello word!\n)     # 在末尾添加换行符f.write(Life is short, you need Python!\n)2.3、附加到文件 
如果要给文件添加内容又不想覆盖原因内容可以使用附加模式打开文件它不会清空原因内容只会在末尾添加如果指定的文件不存在python将创建一个空文件。 
filename  C:\\Users\\hj\\Desktop\\test\\hello.txt
with open(filename, a) as f:#f.write(hello word!\n)     # 在末尾添加换行符#f.write(Life is short, you need Python!\n)f.write(我喜欢Python。\n)
--------------------
hello word!
Life is short, you need Python!
我喜欢Python。练习一 编写一个程序提示用户输入其名字用户做出响应后将其名字写入到文件 guest.txt 中 
name  input(Enter your name: )
filename  C:\\Users\\hj\\Desktop\\test\\guest.txt
with open(filename, w) as f:f.write(name)练习二 编写一个while 循环提示用户输入其名字并打印一句问候语再将访问记录添加到文件guest_book.txt 中确保每条记录独占一行 
filename  C:\\Users\\hj\\Desktop\\test\\guest_book.txt
print(Enter quit when you are finished.)while True:name  input(Enter your name: )if name  quit:breakelse:with open(filename, a) as f:f.write(name  \n)print(Hi   name  , youre been added to the guest book.) 练习三 关于编程的调查编写一个while 循环询问用户为何喜欢编程每当用户输入一个原因后都将其添加到一个存储所有原因的文件中 
filename  C:\\Users\\hj\\Desktop\\test\\reason.txt
responses  []while True:response  input(Enter why do you like programming? )responses.append(response)continue_poll  input(would you like to let someone else respond?(y/n))if continue_poll ! y:breakwith open(filename, a) as f:for response in responses:f.write(response  \n)3、异常 
当发生让python 不知所措的错误时它会创建一个异常对象如果你编写了处理该异常的代码程序将继续执行否则会引发一个错误显示 traceback其中包含异常报告。 
处理异常通常使用try–except 代码块它让python执行指定操作同时报告python发生异常该怎么办即使出现了异常程序也能继续执行而不会出现让用户困惑的traceback。 
3.1、处理 ZeroDivisionError 异常 
这个异常意为除数分母为0的异常以下为一个简单的计算题要用户输入2个数字然后求其商如果没有try–except 代码块当用户输入second name 为0 时程序将奔溃 
print(Give me a two numbers, and Ill divide them.)
print(Enter q to quit.)while True:first_name  input(\nFirst name: )if first_name  q:breaksecond_name  input(\nSecond name: )if second_name  q:breakanswer  int(first_name) / int(second_name)print(answer)
---------------------------------------------
Give me a two numbers, and Ill divide them.
Enter q to quit.First name: 5Second name: 0
Traceback (most recent call last):File C:/Users/hj/PycharmProjects/package/file_reader.py, line 102, in moduleanswer  int(first_name) / int(second_name)
ZeroDivisionError: division by zero 
3.2、使用异常避免崩溃 
发生错误时如果程序还有工作没有完成那么能妥善处理错误就显得尤其重要因此要求在用户输入无效程序发生错误时程序能提示用户提供有效输入。 
**将容易出错的代码放在 try 代码块后except 代码块告诉python如果它尝试运行 try 代码块中的代码时发生了异常该怎么办else 代码块则是在 try 代码块中的代码能成功执行才需要执行的代码。 ** 
print(Give me a two numbers, and Ill divide them.)
print(Enter q to quit.)while True:first_name  input(\nFirst name: )if first_name  q:breaksecond_name  input(\nSecond name: )if second_name  q:breaktry:                   # 添加try-except代码块answer  int(first_name) / int(second_name)except ZeroDivisionError:             # 若用户输入second name 为0则执行这条语句提示用户print(You can not divide by zero)else:               # 若try 代码块中的代码没有发生异常则继续执行这段代码块print(answer)---------------------------------
Give me a two numbers, and Ill divide them.
Enter q to quit.First name: 6Second name: 2
3.03.3、处理 FileNotFoundError 异常 
处理文件时一种常见的问题是找不到文件有可能是你找到文件不存在或者在别的目录从而引发 FileNotFoundError 错误 
filename  alice.txttry:with open(filename) as f:contents  f.readline()except FileNotFoundError:msg  sorry,   filename   does not exist.print(msg)
----------------------------
sorry, alice.txtdoes not exist.3.4、分析文本 
你可以分析包含整本书的文本文件比如计算文件中包含多少个单词我们将使用split方法它可以将一串字符串分隔成若干元素并存储在一个列表中以空格为分隔符 
# programming.py
filename  programming.txttry:with open(filename) as f:contents  f.read()         # 将文件对象读取出来并存储到变量 contents 中
except FileNotFoundError:msg  Sorry, the file   filename   does not exist.print(msg)
else:# 计算文件大致包含了多少个单词words  contents.spilt()             # 将变量 contents 分隔并存储到列表 words 中num_words  len(words)              # 获取列表的长度print(This file   filename   has about   str(num_words)  words.)  # 打印文件中有多少个单词#print(words)
----------------------The fileprogramming.txt has about 4 words.
#[I, love, Python!, hello]3.5、使用多个文件 
下面举例分析计算多个文件看每个文件包含多少个单词特意将new words.txt 没放入程序所在目录测试程序是否能检测出来并正常运行 
def count_words(filename):计算一个文件包含多少个单词try:with open(filename) as f:contents  f.read()except FileNotFoundError:msg  Sorry, the file   filename   does not exist.print(msg)else:words  contents.split()num_words  len(words)print(The file   filename   has about   str(num_words)   words.)filenames  [programming.txt, learning_python.txt, pi_million_digits.txt, new words.txt]
# 将文件名存放到列表 filenames 中
for filename in filenames:       # 遍历列表 filenamescount_words(filename)       # 传入参数filename-----------------------------------
The file programming.txt has about 4 words.
The file learning_python.txt has about 35 words.
The file pi_million_digits.txt has about 10000 words.
Sorry, the file new words.txt does not exist.3.6、pass 语句 
在之前的实例中我们在except 代码块中告诉用户原因但有时并不是每次都需要告知用户原因的我们可以 用 pass 语句使程序在程序发生异常“一声不吭”明确告诉python 什么都不用做 
def count_words(filename):try:with open(filename) as f:contents  f.read()except FileNotFoundError:pass                       # 使用 pass 语句直接跳过else:words  contents.split()num_words  len(words)print(The file   filename   has about   str(num_words)   words.)filenames  [programming.txt, learning_python.txt, pi_million_digits.txt, new words.txt]
for filename in filenames:count_words(filename)
-------------------------The file programming.txt has about 4 words.
The file learning_python.txt has about 35 words.
The file pi_million_digits.txt has about 10000 words.pass 语句还充当了占位符它提醒你在程序的某个地方什么都没有做并且以后也许要在这里做些什么。例如在这个程序中我们可能觉得将找不到的文件名称写入到文件 missing_files.txt 中用户看不到这个文件但我们可以读取这个文件进而处理所有文件找不到的问题。 
3.7、决定报告哪些错误 
什么情况下该向用户报告错误又在什么情况下异常时一声不吭 
若用户知道要分析哪些文件他们可能希望在有文件没有分析时出现一条消息就将原因告诉他们若用户只想看到结果而不关心要分析哪些文件那么就一声不吭向用户显示他不想看到的信息会降低程序的可用性。 
编写好的程序经过测试不易出现内部错误但只要程序依赖于外部因素如输入、存在指定文件、网络连接等就有可能出现异常凭借经验可判断该在何时添加异常处理块以及是否该向用户提供多少相关信息。 
4、存储数据 
很多程序都要求用户输入某种信息如存储游戏首选项或提供可视化的数据不管是什么程序都把信息存储在列表和字典等数据结构中用户关闭程序时保存信息一种简单的方式就是使用json 模块来存储数据。 
json 模块能将简单的python数据转存到文件中并在程序再次运行时加载该文件json 是跨平台的并非只有python能用其他语言也可以使用因此可以分享给别人。 
4.1、使用 json.dump和 json.load 
json.dump函数用来将文件存储到文件它接受两个实参要存储的数据、用于存储数据的文件对象json.load函数用于程序再次运行加载文件到内存 
# 将一个列表存储到文件中使用json模块
import json     # 导入 json 模块numbers  [2, 3, 4, 5, 6]   # 定义一个列表
file_name  json_file.jsonwith open(file_name, w) as f:         # 使用写入模式json.dump(numbers, f)  # 将numbers 转存到file_name中 
运行程序没有输出但打开 json_file.json 文件numbers 数据已经存储到其中。 
再编写一个程序使用 json.load函数将这个列表读取到内存中 
import jsonfile_name  json_file.json
with open(file_name) as f:numbers  json.load(f)  # 使用json.load将数据加载到内存print(numbers)
-------------------------------------------------
[2, 3, 4, 5, 6]4.2、保存和读取用户生成的数据 
使用 json 模块保存数据有个好处它能在你下次运行程序时记住你的信息比如下面例子用户首次运行程序被要求输入其名字待再次运行程序时程序就已经记住他了 
# remember_me.py
import jsonfile_name  username.jsontry:with open(file_name) as f:       # 使用异常代码块判断用户是否是首次输入若是首次文件不存在则执行except 代码块要求用户输入名字username  json.load(f)
except FileNotFoundError:            username  input(Whats your name? )with open(file_name, w) as f:json.dump(username, f)               # 将用户名写入文件中此时程序已经记住用户名print(Well remember you when you come back,   username  !)
else:print(Welcome back,   username  !)
------------------------------------------------------
# 用户首次运行时结果
Whats your name? alice
Well remember you when you come back, alice!# 用户再次运行程序时结果
Welcome back, alice!4.3、重构 
有时会遇到这样的情况程序能够正确运行但是可以进一步改进—将代码划分为一系列的具体工作函数这种过程称为重构它可以使代码更清晰、更易于理解、更易拓展。 
要重构 remember_me.py 我们可以将其大部分逻辑放到一个或多个函数中它的重点是问候因此我们将其放入到一个名为 great_user 的函数中 
# remember_me.py
import jsondef great_user():问候用户并指出其名file_name  username.jsontry:with open(file_name) as f:username  json.load(f)except FileNotFoundError:username  input(Whats your name? )with open(file_name, w) as f:json.dump(username, f)print(Well remember you when you come back,   username  !)else:print(Welcome back,   username  !)
great_user()考虑到使用一个函数它不仅问候用户还在存储用户名时获取它而在没有存储用户名时提示用户输入所有的任务都在一个函数中我们觉得再重构它将其获取用户名的代码转移到另外一个函数get_stored_username中提示用户输入的放入另外一个函数get_new_username中 
import jsondef get_stored_name():            # 判断文件是否存在要是不存在就返回一个空否则返回用户名如果存储了用户名就获取它file_name  user_name.jsontry:with open(file_name) as f:username  json.load(f)except FileNotFoundError:return Noneelse:return usernamedef get_new_username():         # 如果文件存在即用户名存在因为返回的也是用户名故不执行否则提示用户用户输入用户名提示用户输入用户名username  input(Whats your name? )file_name  user_name.jsonwith open(file_name, w) as f:json.dump(username, f)return usernamedef great_user():问候用户并指出其名username  get_stored_name()  # 若文件存在返回值为用户名即为真否则返回值为空假if username:    # 返回值为真时执行print(Welcome back,   username  !)else:        # 返回值为假时执行username  get_new_username()print(Well remember you when you come back,   username  !)great_user()
----------------------------------
# 首次运行
Whats your name? alice
Well remember you when you come back, alice!# 第二次运行
Welcome back, alice!我们调用great_user它打印一条合适的消息要么欢迎老用户回来要么问候新用户为此它首先调用get_stored_name这个函数只负责获取存储的用户名若存储了的话再在必要时调用get_new_username这个函数只负责获取并存储新用户的用户名每个函数分工合作。 练习 验证用户remember_me.py 中当前和最后一次运行该程序的用户并非同一人为此我们可以在great_user中打印用户回来的消息前首先询问他用户名是否正确如果不对就调用get_new_username让用户输入正确的用户名 
# remember_me.py
import jsondef get_stored_name():--snip--def get_new_username():--snip--def great_user():问候用户并指出其名username  get_stored_name()if username:correct  input(Are you   username  ? (y/n) )if correct  y:print(Welcome back,   username  !)else:username  get_new_username()print(Well remember you when you come back,   username  !)else:username  get_new_username()print(Well remember you when you come back,   username  !)great_user()
---------------------------------------------
Are you alice? (y/n) n
Whats your name? lila
Well remember you when you come back.附录 
常见的Python 异常 
AssertionError断言语句失败 
当assert 关键字后的条件为假时程序停止抛出AssertionError异常。 a  [2, 3, 4]assert len(a)  0
Traceback (most recent call last):File pyshell#1, line 1, in moduleassert len(a)  0
AssertionErrorAttributeError当访问的对象属性不存在时抛出异常 my_fish  [2, 3, 4]my_fish.goldfish
Traceback (most recent call last):File pyshell#3, line 1, in modulemy_fish.goldfish
AttributeError: list object has no attribute goldfishIndexError索引超出序列范围 a  [2, 3, 4]a[3]
Traceback (most recent call last):File pyshell#6, line 1, in modulea[3]
IndexError: list index out of rangeKeyError字典中查找一个不存在的关键字 
当在字典中查找一个不存在的关键字时引发KeyError 异常 my_dict  {one: 1, two: 2}my_dict[three]
Traceback (most recent call last):File pyshell#9, line 1, in modulemy_dict[three]
KeyError: threeNameError尝试访问一个不存在的变量 name
Traceback (most recent call last):File pyshell#10, line 1, in modulename
NameError: name name is not definedOSError操作系统产生的异常 
这是操作系统引发的异常因素有很多网络、系统或其他与FileNotFoundError 找不到文件差不多FileNotFoundError 是 OSError 的子类。 
SyntaxError语法错误 
一般会提示你哪里语法错误找出修改即可 print heelo
SyntaxError: Missing parentheses in call to printTypeError不同类型间的无效操作 1  1
Traceback (most recent call last):File pyshell#12, line 1, in module1  1
TypeError: unsupported operand type(s) for : int and strIndentationError缩进错误 
a  3
if a  1:
a  1
-----------------------------------------------File C:/Users/hj/PycharmProjects/package/file_reader.py, line 272a  1^
IndentationError: expected an indented blockValueError传入无效的参数 
import mathx1  math.sqrt(-1)    # math 模块中的sqrt函数是用来计算非负实数的平方根即参数为非负实数
print(x1)
-----------------------
Traceback (most recent call last):File C:/Users/hj/PycharmProjects/package/file_reader.py, line 273, in modulex1  math.sqrt(-1)
ValueError: math domain errorZeroDivisionError 除数为零FileNotFoundError文件不存在或者不在索引目录