python编程学习笔记⑨文件和异常

文件和异常
10.1.1读取整个文件
关键字with----在不再需要访问文件后关闭。
函数open() -----打开文件
close() -----关闭文件
方法read() ----读取文件
方法rstrip()—删除空白(字符串末尾)

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

10.1.2文件路径
相对路径

with open('text/pi_digits.txt') as kingnsl:

绝对路径

with open('/hometext/pi_digits.txt') as kingnsl:

10.1.3逐行读取
使用for循环遍历

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

10.1.4创建一个包含文件各行内容的列表
方法readlines()—从文件中读取每一行,并将其储存在一个列表中。

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

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

10.1.5使用文件的内容
方法strip()删除所有空格

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

pi_string = ''
for line in lines:
	pi_string += line.strip()  #这里是方法strip()
print(pi_string)
print(len(pi_string))

使用float()转换字符串为浮点数,只能显示小数点后15位?
10.1.6包含一百万位的大型文件

print(f"{pi_string[:50]}")

10.1.7圆周率值中包含你的生日吗

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()
birthday = input("请输入你的生日,如:201130:")
if birthday in pi_string:
	print("你的生日出现在圆周率的第一个百万位数")
else:
	print("你的生日不会出现在圆周率的第一个百万位数中")

练习10-1:python学习笔记

filename = 'learning_python.txt'

print("读取整个文件")
with open(filename) as file_object:
	tachyon = file_object.read()

print(tachyon)
print("\n遍历文件对象")
with open(filename) as file_object:
	for tachyon in file_object:
		print(tachyon.rstrip())

print("\n文件储存在列表中")
with open(filename) as file_object:
	tachyons = file_object.readlines()
for tachyon in tachyons:
	print(tachyon.rstrip())
输出:
读取整个文件
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.

遍历文件对象
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.

文件储存在列表中
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.
[Finished in 0.1s]

练习10-2:C语言学习笔记
使用方法replace()替换字符串。

filename = 'learning_python.txt'

print("原文件")
with open(filename) as file_object:
	tachyons = file_object.readlines()
for tachyon in tachyons:
	print(tachyon.rstrip())

print("\n修改Python为C")
with open(filename) as file_object:
	tachyons = file_object.readlines()
for tachyon in tachyons:
	print(tachyon.replace('Python', 'C').rstrip())
输出:
原文件
In Python you can store as much information as you want.
In Python you can connect pieces of information.
In Python you can model real-world situations.

修改Python为C
In C you can store as much information as you want.
In C you can connect pieces of information.
In C you can model real-world situations.
[Finished in 0.1s]

替换严格大小写
如果读取的文件使用中文可将

with open(filename) as file_object:
改为:
with open(filename, encoding="utf8") as file_object:

10.2写入文件
10.2.1写入空文件
open()的第二个实参,‘w’ 写入模式,‘r’读取模式,‘a’附加模式,‘r+’读写模式。
如何省略默认是只读模式。
如何写入文件不存在,open()函数会自动创建。

filename = 'programming.txt'

with open(filename, 'w') as file_object:  #字符串写入到文件
	file_object.write('I love programming')

with open(filename, 'a', encoding='utf8') as file_object: #中文字符串写入到文件
	file_object.write('\n我爱祖国')

with open(filename, 'a') as file_object: #数字写入到文件
	file_object.write('\n' + str(123456))

10.2.2写入多行

filename = 'programming.txt'

with open(filename, 'w', encoding='utf8') as file_object: 
	file_object.write('\n我爱祖国')
	file_object.write('\n我爱祖国')
	file_object.write('\n我爱祖国')
	file_object.write('\n' + str(999))

10.2.3附加到文件
使用实参’a’。
练习10.-3:访客

filename = 'guest.txt'
kingnsl = input('请输出你的名字:')
with open(filename, 'a', encoding='utf8') as file_object:
	file_object.write('\n' + kingnsl)

练习10-4:访客名单

filename = 'guest_book.txt'

while True:
	name = input("请输出你的名字:")
	if name == 'q':
		break
	else:
		print(f"你好{name}")
	with open(filename, 'a', encoding='utf8') as f:
		f.write('\n' + name)

练习10-5:调查
其实10-4的写法就可以,这里是另一种写法

filename = '原因.txt'

responses = []
while True:
	response = input("写出你喜欢编程的原因:")
	responses.append(response)

	continue_poll = input("是否继续填写?(y/n)")
	if continue_poll != 'y':
		break	
with open(filename, 'a', encoding='utf8') as f:
	for response in responses:
		f.write(f"{response}\n")

10.3异常
10.3.1处理ZeroDivisionError异常
将引发异常的代码包在try-except代码块中
如:

try:
    print(5/0)
except ZeroDivisionError:
    print("不可以除以0")

常见应用:如提示用户输入错误:
这样程序就可以继续执行,而不是有错误后停止。

print("给我两个数,我来除以它们")
print("输入'q'退出计算。")

while True:
    first_number = input("\n输入第一个数:")
    if first_number == 'q':
        break
    second_number = input("\n输入第二个数:")
    if second_number == 'q':
        break
    try:
        answer = int(first_number) / int(second_number)
    except ZeroDivisionError:
        print("不能除以0")
    else:
        print(answer)

10.3.5处理FileNotFoundError异常
和ZeroDivisionError类似
如:假设没有alice.txt这个文件

filename = 'alice.txt'

try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"找不到{filename}这个文件")

10.3.6分析文件
方法split() ----根据一个字符串创建一个单词列表
如:我们想知道alice.txt这本书有多少个字

filename = 'alice.txt'

try:
    with open(filename, encoding='utf-8') as f:
        contents = f.read()
except FileNotFoundError:
    print(f"找不到{filename}这个文件")
else:
    words = contents.split()
    num_words = len(words)
    print(f"爱丽丝漫游奇境记一书有{num_words}个字。")
  输出:
  爱丽丝漫游奇境记一书有29465个字。
[Finished in 0.1s]

10.3.7使用多少个文件

在这里插入代码片def count_words(filename):
    """计算一个文件大致包含多少个单词"""

    try:
        with open(filename, encoding='utf-8') as f:
            contents = f.read()
    except FileNotFoundError:
        print(f"找不到{filename}这个文件")
    else:
        words = contents.split()
        num_words = len(words)
        print(f"{filename}这本书大致有{num_words}个字。")

filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little.txt']
for filename in filenames:
    count_words(filename)
输出:
alice.txt这本书大致有29465个字。
siddhartha.txt这本书大致有42172个字。
moby_dick.txt这本书大致有215830个字。
找不到little.txt这个文件
[Finished in 0.1s]

使用了try-except代码块,有两个优点:1、避免用户看到traceback错误。2、让程序继续分析能找到其他文件
10.3.8静默失败
pass语句的使用
把上面示例改成:

except FileNotFoundError:
        print(f"找不到{filename}这个文件")
改成:
except FileNotFoundError:
        pass

如下:

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"{filename}这本书大致有{num_words}个字。")

filenames = ['alice.txt', 'siddhartha.txt', 'moby_dick.txt', 'little.txt']
for filename in filenames:
    count_words(filename)
输出:
alice.txt这本书大致有29465个字。
siddhartha.txt这本书大致有42172个字。
moby_dick.txt这本书大致有215830个字。
[Finished in 0.1s]

10.3.9决定报告哪些错误
适当的使用显示错误,适当的时候静默处理。

练习10-6:加法运算
ValueError异常

print("计算2个数相加")
x = input("输入第一个数:")
y = input("输入第二个数:")
try:
	z = float(x) + float(y)
	print(f"{x}加{y}等于{z}")
except ValueError:
	print("你输入的不是一个数值")
输出:
计算2个数相加
输入第一个数:2
输入第二个数:3
23等于5.0
-----------
计算2个数相加
输入第一个数:1
输入第二个数:w
你输入的不是一个数值

练习10-7:加法计算器

print("加法计算器")
while True:
	first_number = input("输入第一个数值:")
	if first_number == 'q':
		break
	second_number = input("输入第二个数值:")
	if second_number == 'q':
		break
	try:
		answer = int(first_number) + int(second_number)
		print(answer)
	except ValueError:
		print("你输入的不是一个数值")
输出:
加法计算器
输入第一个数值:十
输入第二个数值:五
你输入的不是一个数值
输入第一个数值:10
输入第二个数值:5
15

练习10-8:猫和狗

filenames = ['cats.txt', 'dogs.txt']

for filename in filenames:
	try:
		with open(filename, encoding='utf-8') as f:
			kingnsl = f.read()
			print(kingnsl)
	except FileNotFoundError:
		print(f"找不到文件{filename}")
输出:
小爱猫
猪猪猫
小花猫
找不到文件dogs.txt
[Finished in 0.1s]

练习10-9:静默的猫和狗

filenames = ['cats.txt', 'dogs.txt']

for filename in filenames:
	try:
		with open(filename, encoding='utf-8') as f:
			kingnsl = f.read()
			print(kingnsl)
	except FileNotFoundError:
		pass
输出:
小爱猫
猪猪猫
小花猫
[Finished in 0.1s]

练习10-10:常见单词
方法count()----确定特定的单词或短语在字符串中出现了多少次。

def count_read(filename, word):
	"""计算单词在字符串中出现了多少次"""
	try:
		with open(filename, encoding='utf-8') as f:
			contens = f.read()
	except FileNotFoundError:
		print(f"找不到文件{filename}")
	else:
		kingnsl = contens.lower().count(word)
		msg = f"'{word}'在{filename}中出现了{kingnsl}次" #注意{word}是单引号内
		print(msg)

filename = 'alice.txt'
count_read(filename, 'the')
输出:
'the'在alice.txt中出现了2505[Finished in 0.1s]

10.4储存数据
模块json(JavaScript Object Notation)
下面示例将一组数字列表,储存以.json扩展名的文件中。我们使用函数json.dump()储存数字列表到文件number.json
json.dump(number, f)它有2个实参。

import json

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

filename = 'number.json'
with open(filename, 'w') as f:
	json.dump(number, f)

函数json.load() ----读取到内存

import json

filename = 'number.json'
with open(filename) as f:
	number = json.load(f)
print(number)

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

import json

#如果以前储存了用户名,就加载它,否则,提示用户输入用户名并储存它
#这里使用了try-except代码块,当文件不存在时继续执行后面的代码。

filename = 'username.json'

try:
	with open(filename) as f:
		username = json.load(f)
		
except FileNotFoundError:
	username = input("你叫什么名字:")
	with open(filename, 'w') as f:
		json.dump(username, f)
		print(f"你的用户名是{username}")
else:
	print(f"欢迎回来{username}")

思考:这个程序如果第1次打开直接回车,就是个空用户名,如何解决。
如果把生成了username.json文件内容删除,程序会报错:son.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)。
10.4.3重构
先将前面示例写在一个名为:greet_user的函数里

import json

def greet_user():
	"""问候用户,并指出其名字"""
	filename = 'username.json'

	try:
		with open(filename) as f:
			username = json.load(f)
		
	except FileNotFoundError:
		username = input("你叫什么名字:")
		with open(filename, 'w') as f:
			json.dump(username, f)
			print(f"你的用户名是{username}")
	else:
		print(f"欢迎回来{username}")

greet_user()

这个函数集合了3个功能:1、如果储存了用户名,就获取它。2、当储存了用户名它显示欢迎语。3、当没有文件时候提示用户输入用户名。
重构代码就是把每一个功能单独的用函数表示,以达到单一而清晰的任务。

import json

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

def get_new_username():
	"""提示用户输入用户名"""
	username = input("请输入你的名字:")
	filename = 'username.json'
	with open(filename, 'w') as f:
		json.dump(username, f)
	return username

def greet_user():
	"""问候用户,并指出其名字"""
	username = get_stored_username()
	if username:
		print(f"欢迎回来{username}")
	else:
		username =get_new_username()
		print(f"你的用户名是{username}")

greet_user()

练习10-11:喜欢的数
10-11-1.py

import json

filename = 'user_number.json'
user_number = input("输入你喜欢的数字:")

with open(filename, 'w') as f:
	json.dump(user_number, f)

10-11-2.py

import json

filename = 'user_number.json'

with open(filename) as f:
	user_number = json.load(f)
print(f"I know favorite number! It's {user_number}") 

练习10-12:记住喜欢的数

import json

filename = 'user_number.json'

try:
	with open(filename) as f:
		user_number = json.load(f)
	
except FileNotFoundError:
	user_number = input("输入你喜欢的数字:")

	with open(filename, 'w') as f:
		json.dump(user_number, f)
else:
	print(f"I know favorite number! It's {user_number}") 

练习10-13:验证用户
这个题的关键在于,如果是另一个用户运行了该程序该如何办?因此我们需要在函数def greet_user()加入if判断。

import json

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

def get_new_username():
	"""提示用户输入用户名"""
	username = input("请输入你的名字:")
	filename = 'username.json'
	with open(filename, 'w') as f:
		json.dump(username, f)
	return username

def greet_user():
	"""问候用户,并指出其名字"""
	username = get_stored_username()
	if username:
		correct = input(f"这{username}是你的用户名吗?(y/n)")
		if correct == 'y':
			print(f"欢迎{username}回来")
		else:
			username = get_new_username()
			print(f"欢迎{username}回来")
	else:
		username =get_new_username()
		print(f"你的用户名是{username}")



greet_user()

你可能感兴趣的:(python3编程学习笔记,josn,重构,文件和异常,python)