第十四章 文件读写
14.1 文件读操作
读取文本时,python将其中的所有文本都解读为字符串
语法规则:file = open(filename [,mode,encoding])
- file:被创建的文件对象
- open:创建文件对象的函数
- filename:要创建或打开的文件名称
- mode:打开默认为只读
- encoding:默认文本文件中字符的编写格式为gbk
例:读取磁盘文件的内容
file = open('a.txt', 'r') # 只读形式打开a.txt print(file.readlines()) # 逐行读取,返回列表,每行为以列表元素 file.close() # 打开之后都要关闭
['中国\n', '美丽']
方法二,效果一样,且不需close
with open('a.txt', 'r') as file: # 默认为只读,'r'其实可以省略 print(file.readlines())
14.2 文件写操作
例:新文件中写入一行
filename = "abc.txt" with open(filename, 'w') as file_object: file_object.write("zdb\n")
例:追加到旧文件中写入
filename = "abc.txt" with open(filename, 'a') as file_object: file_object.write("zzz\n") #在上面原有文件里追加一行数据
14.3 常用的文件打开模式
按文件中数据的组织形式,文件分为以下两大类
- 文本文件:存储的是普通“字符文本”,默认为unicode字符集,可以使用记本事程序打开
- 二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件打开,举例:mp3音频文件,jpg图片,doc文档等
打开模式 | 执行操作 |
‘r’ | 以只读方式打开文件(默认) |
‘w’ | 以写入的方式打开文件,会覆盖已存在的文件 |
‘x’ | 如果文件已经存在,使用此模式打开将引发异常 |
‘a’ | 以写入模式打开,如果文件存在,则在末尾追加写入 |
‘b’ | 以二进制模式打开文件,不能单独使用,需要与其它模式一起使用,如rb,wb |
‘t’ | 以文本模式打开(默认) |
‘+’ | 以读写模式打开,不能单独使用,需要与其它模式一起使用,如a+ |
‘U’ | 通用换行符支持 |
‘w’
1、open以写入的方式打开一个不存在的文件,便能创建一个新文件
file = open('b.txt', 'w') file.write('helloworld') file.close()
2、再次以写入的形式写进创建好的文件,便覆盖文件的内容
file = open('b.txt', 'w') file.write('python') file.close()
例2:
这里有两种打开文件的方法,同时两种写入文件的方法
# 一,使用print方式进行输出() fp = open('text.txt', 'w') print('奋斗成就更好的你', file=fp) # 这里也可以f.write() fp.close() """第二种方式,使用文件读写操作""" with open('text1.txt', 'w') as file: file.write('奋斗成就更好的你')
‘a’
把上述代码的’w’改成’a’,再运行一次,便在原来的基础上追加,所以结果显示两个python
file = open('b.txt', 'a') file.write('python') file.close()
但如果原来没有这个文件,便创建,如以下代码在不存在的c文件中写入
file = open('c.txt', 'a') file.write('python') file.close()
‘b’
这里进行图片的赋值,原图片为win.png,复制后命名为copy.png
# 进行图片的复制 src_file = open('win.png', 'rb') # 原文件,二进制读 target_file = open('copy.png', 'wb') # 目标文件,二进制写 target_file.write(src_file.read()) # 原文件读出,写入目标文件 target_file.close() # 关闭两个文件 src_file.close()
结果如下:
14.4 文件对象的常用方法
文件对象方法 | 执行操作 |
read([size]) | 从文件中读取size个字节或字符的内容返回。若省略[size],则读取到文件末尾,即一次读取文件所有内容 |
readline() | 从文本文件中读取一行内容 |
readlines() | 把文本文件中每一行都作为独立的字符串对象,并将这些对象放入列表返回 |
write(str) | 将字符串str内容写入文件 |
wirtelines(s_list) | 将字符串列表s_list写入文本文件,不添加换行符 |
seek(offset[,whence]) | 把文件指针移动到新的位置,offset表示相对于whence的位置;offset为正往结束方向移动,为负往开始方向移动。whence不同的值代表不同含义:0:从文件头开始计算(默认值);1:从当前位置开始计算;2:从文件尾开始计算 |
tell() | 返回文件指针的当前位置 |
truncate([size=file.tell()]) | 截取文件到size个字节,默认是截取到文件指针当前位置 |
flush() | 把缓冲区的内容写入文件,但不关闭文件 |
close() | 关闭文件 |
read():读出
file = open('a.txt', 'r') print(file.read())
readline():读一行
file = open('a.txt', 'r') #print(file.read()) print(file.readline())
readlines():将每一行元素作为独立字符串,放入列表当中
file = open('a.txt', 'r') #print(file.read()) #print(file.readline()) print(file.readlines())
['中国\n', '美丽']
write():写入
file = open('c.txt', 'w') file.write('hello') file.close()
writelines():将字符串列表s_list写入文本文件,不添加换行符
file = open('c.txt', 'a') lst = ['java', 'go', 'python'] file.writelines(lst) file.close()
seek()
file = open('a.txt', 'r') file.seek(2) # 一个中文两个字节,跳过了国字 print(file.read()) print(file.tell()) # 中国,回车,美丽总共10字节 file.close()
国 美丽 10
tell()
file = open('b.txt', 'r') print(file.read()) print(file.tell()) # 中国,回车,美丽总共10字节 file.close()
pythonpython 12
flush()
file = open('d.txt', 'a') file.write('hello') file.flush() # 后面可以继续写内容 file.write('world') file.close() # 后面不可以写代码
encoding=‘utf-8’
f = open('C:\\Users\\zdb\\Desktop\\abc.txt', encoding='utf-8') #encoding='utf-8' 防止乱码加上去的 print(f) print(f.read()) #对的,读,并输出
<_io.TextIOWrapper name='C:\\Users\\zdb\\Desktop\\abc.txt' mode='r' encoding='utf-8'> abcdefg
例2
file_name = input('请输入需要打开的文件名:') f = open(file_name) print('文件的内容是:') for each_line in f: print(each_line)
with open(‘a.txt’, ‘r’) as file::这样就不需要关闭文件那一行代码了
with open('a.txt', 'r') as file: print(file.read())
中国 美丽
例2
with open('win.png', 'rb') as file: # 以二进制读打开 with open('copy.png', 'wb') as target_file: # 以二进制写打开 target_file.write(file.read()) # 目标文件写入原文件被读的
14.5 文件路径:相对路径、绝对路径
相对路径:只能读取到同一目录里面的文件
- 1、text_files与主程序在一个目录
- 2、读取text_file里面的pi_digits.txt
- 3、主程序代码如下
with open('text_files\pi_digits.txt') as file_object: #open接受一个参数:要打开的文件的名称 #关键字with在不需要访问文件后将其关闭 contents = file_object.read() #read读取这个文件的全部内容,并将其作为长串字符存储在变量contents中 print(contents) #打印输出
绝对路径:读取系统任何地方的文件
f = open('C:\\Users\\zdb\\Desktop\\abc.txt', encoding='utf-8') #encoding='utf-8' 防止乱码加上去的 print(f) print(f.read()) #对的,全输出
例2
f = open('C:\\Users\\zdb\\Desktop\\abc.txt', encoding='utf-8') #f.seek(0,0) lines = list(f) for each_line in lines: print(each_line.rstrip()) #rstrip去掉\n
abcdefg 123 456
第十五章 组织文件
15.1 shutil模块复制、移动、删除、改名文件\文件夹
1. 复制文件:shutil.copy()
例:源文件在桌面,名为a.txt
import shutil, os os.chdir('C:\\Users\\zdb\\Desktop\\') # 设置工作路径 shutil.copy('C:\\Users\\zdb\\Desktop\\a.txt', 'E:\\') # 复制到E盘 shutil.copy('C:\\Users\\zdb\\Desktop\\a.txt', 'E:\\b.txt') # 重新命名为b.txt
2. 复制文件夹:shutil.copytree()
例:源文件在桌面上,a文件夹里面有个a.txt
import shutil, os os.chdir('C:\\Users\\zdb\\Desktop\\') shutil.copytree('C:\\Users\\zdb\\Desktop\\a', 'E:\\b') # 复制到E盘文件夹命名为b
3. 移动文件:shutil.move()
例1:源文件在a下a.txt,E盘有个空文件夹b
import shutil, os os.chdir('C:\\Users\\zdb\\Desktop\\') shutil.move('C:\\Users\\zdb\\Desktop\\a\\a.txt', 'E:\\b') # 把TXT移动到E盘b文件夹
例2:移动文件,且重命名:桌面有a\a.txt,把它移动到E盘b文件夹,且重命名为b.txt(实现改名)
注意:若目标文件b夹不存在会报错
import shutil, os os.chdir('C:\\Users\\zdb\\Desktop\\') shutil.move('C:\\Users\\zdb\\Desktop\\a\\a.txt', 'E:\\b\\b.txt') # 把TXT移动到E盘b文件夹,且重命名b
3. 删除文件
- 用os.unlink(path)将删除path处的文件
- 用os.rmdir(path)将删除path处的文件夹。该文件夹必须为空
- 用shutil.rmtree(path)将删除path处的文件夹。文件夹中所有文件也删除
注意:删除不可逆,不要轻易删除,最好先打印输出一遍要删除的文件,防止删错文件
import os for filename in os.listdir(): if filename.endswith('.rxt'): print(filename) #os.unlink(filename)
- shutil.rmtree()函数删除不可逆,但是使用send2trash模块可以删除到回收站,而不是永久删除跳过回收站
import send2trash file = open('C:\\Users\\zdb\\Desktop\\a.txt', 'a') # 创建a.txt file.write('abc123') # 写入数据 file.close() # 关闭文件 send2trash.send2trash('C:\\Users\\zdb\\Desktop\\a.txt') #删除到回收站
15.2 处理压缩文件:读取、解压、创建
1. 读取zip文件
要读取zip文件,就要先创建一个ZipFile对象,用zipfile.ZipFile()函数创建
例:example压缩包中有a文件夹和c.txt文件,a文件夹下还有a.txt和b.txt
import zipfile, os os.chdir('C:\\Users\\zdb\\Desktop\\') example_zip = zipfile.ZipFile('example.zip') print(example_zip.namelist()) # 输出文件名列表 file = example_zip.getinfo('c.txt') print(file.file_size) # 输出源文件大小 print(file.compress_size) # 输出压缩后文件大小 example_zip.close()
['a/', 'a/a.txt', 'a/b.txt', 'c.txt'] 0 0
2. 从zip文件中解压缩
- ZipFile对象的extractall()方法从zip文件中解压缩所有文件和文件夹,放到当前工作目录中
import zipfile, os os.chdir('C:\\Users\\zdb\\Desktop\\') example_zip = zipfile.ZipFile('example.zip') example_zip.extractall() example_zip.close()
解压前:
解压后如下:压缩包不会消失
- example_zip.extract()可解压单个文件,第一个参数指定需解压的文件;第二个参数指定路径
import zipfile, os os.chdir('C:\\Users\\zdb\\Desktop\\') example_zip = zipfile.ZipFile('example.zip') example_zip.extract('c.txt', 'C:\\Users\\zdb\\Desktop\\') # 将c.txt解压到桌面 example_zip.close()
3. 创建和添加到zip文件
- 要创建压缩文件需要用写的形式打开文件,write()写入,第一个参数表示需要压缩的文件,第二个参数是“压缩类型”参数。
import zipfile, os os.chdir('C:\\Users\\zdb\\Desktop\\') new_zip = zipfile.ZipFile('new.zip', 'w') new_zip.write('c.txt', compress_type=zipfile.ZIP_DEFLATED) # 把c.txt添加到new_zip里面 new_zip.close()
第十六章 测试代码
16.1 测试函数
1、编写name_function.py模块
def get_formatted_name(first, last): """生成整洁的姓名""" full_name = first + ' ' + last return full_name.title()
2、在names.py中测试
from name_function import get_formatted_name print("Enter 'q' at any time to quit.") while True: first = input("\nPlease give me a first name: ") if first == 'q': break last = input("Please give me a last name: ") if last == 'q': break formatted_name = get_formatted_name(first, last) #创建实例 print("\tNeatly formatted name: " + formatted_name + '.')
3、输出
Enter 'q' at any time to quit. Please give me a first name: z Please give me a last name: db Neatly formatted name: z db. Please give me a first name: z Please give me a last name: q
可以发现我们每次修改name_function.py,都要重新运行names.py,然后重新输入姓名,这样太繁琐了。Python标准库中的模块unittest提供了代码测试工具。
(1)可通过的测试
先导入模块unittest以及要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。
1、在test_name_function.py中测试name_function.py里面的get-formatted_name()
#导入unittest模块 import unittest #导入要测试的模块函数 from name_function import get_formatted_name #创建NameTestCase类,继承unittest.TestCase父类 class NamesTestCase(unittest.TestCase): """测试name_function.py""" #定义方法 def test_first_last_name(self): """能够正确地处理像Janis Joplin这样的姓名吗?""" #创建实例,存储在formatted_name中 formatted_name = get_formatted_name('janis', 'joplin') #断言方法,用来核实得到的结果是否和期望的结果一致 #两个参数进行比较 self.assertEqual(formatted_name, "Janis Joplin") unittest.main()
这样测试是不是比上面的方法要方便很多
(2)不能通过的测试
1、修改name_function.py,使其包含中间名
2、运行test_name_function.py,输出
E ====================================================================== ERROR: test_first_last_name (__main__.NamesTestCase) 能够正确地处理像Janis Joplin这样的姓名吗? ---------------------------------------------------------------------- Traceback (most recent call last): File "C:/Users/zdb/PycharmProjects/untitled/temp.py", line 14, in test_first_last_name formatted_name = get_formatted_name('janis', 'joplin') TypeError: get_formatted_name() missing 1 required positional argument: 'last' ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1)
(3)测试未通过怎么办
测试未通过时,不要修改测试,而应修复导致测试不能通过的代码
1、使中间名变设置成可选的
def get_formatted_name(first, last, middle=''): """生成整洁的姓名""" if middle: full_name = first + ' ' + middle + ' ' + last else: full_name = first + ' ' + last return full_name.title()
2、运行test_name_function.py,输出
(4)添加新测试
例:添加一个包含中间名的测试
1、在NamesTestCase类中再添加一个方法:
#导入unittest模块 import unittest #导入要测试的模块函数 from name_function import get_formatted_name #创建NameTestCase类,继承unittest.TestCase父类 class NamesTestCase(unittest.TestCase): """测试name_function.py""" #定义方法 def test_first_last_name(self): """能够正确地处理像Janis Joplin这样的姓名吗?""" #创建实例,存储在formatted_name中 formatted_name = get_formatted_name('janis', 'joplin') #断言方法,用来核实得到的结果是否和期望的结果一致 #两个参数进行比较 self.assertEqual(formatted_name, "Janis Joplin") def test_first_last_middle_name(self): """能够正确地处理像Wolfgang Amadeus Mozart这样的姓名吗?""" formatted_name = get_formatted_name('wolfgang', 'mozart', 'amadeus') self.assertEqual(formatted_name, "Wolfgang Amadeus Mozart") unittest.main()
16.2 测试类
各种断言方法
方法 | 用途 |
assertEqual | 核实a == b |
assertNotEqual | 核实a != b |
assertTrue(x) | 核实x为True |
assertFalse(x) | 核实x为False |
assertIn(item, list) | 核实item在list中 |
assertNotIn(item, list) | 核实item不在list中 |
(1)一个要测试的类
1、创建survey.py
class AnonymousSurvey(): """收集匿名调查问卷的答案""" def __init__(self, question): """存储一个问题,并为存储答案做准备""" self.question = question self.responses = [] #答案设置空列表 def show_question(self): """显示调查问卷""" print(self.question) def store_response(self, new_response): """存储单份调查问卷""" self.responses.append(new_response) def show_results(self): """显示搜集到的所有问卷""" print("Survey results:") for response in self.responses: print('- ' + response)
2、在language_survey.py中测试
from survey import AnonymousSurvey #定义一个问题,并创建一个表示调查的AnonymousSurvey对象 question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) #显示问题并存储答案 my_survey.show_question() print("Enter 'q' at any time to quit.\n") while True: #一直循环,直到输入q跳出 response = input("Language: ") if response == 'q': break my_survey.store_response(response) #显示调查结果 print("\nThank youto everyone who participated in the survey!") my_survey.show_results()
3、输出
What language did you first learn to speak? Enter 'q' at any time to quit. Language: English Language: python Language: math Language: q Thank youto everyone who participated in the survey! Survey results: - English - python - math
(2)测试AnonymousSurvey类
import unittest from survey import AnonymousSurvey #导入要测试的类 class TestAnonymousSurvey(unittest.TestCase): #继承了父类 """针对AnonymousSurvey类的测试""" def test_store_single_response(self): """测试单个答案会被妥善地存储""" question = "What language did you first learn to speak?" my_survey= AnonymousSurvey(question) #创建实例 my_survey.store_response('English') self.assertIn('English', my_survey.responses) unittest.main()
测试三个
import unittest from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): """针对AnonymousSurvey类的测试""" def test_store_single_response(self): """测试单个答案会被妥善地存储""" question = "What language did you first learn to speak?" my_survey= AnonymousSurvey(question) my_survey.store_response('English') self.assertIn('English', my_survey.responses) def test_store_three_responses(self): """测试三个答案会被妥善地存储""" question = "What language did you first learn to speak?" my_survey = AnonymousSurvey(question) responses = ['English', 'python', 'C'] for response in responses: my_survey.store_response(response) for response in responses: self.assertIn(response, my_survey.responses) #核实response在my_survey.responses中 unittest.main()
输出
(3)方法setUp()
上面每个测试方法都创建了一个AnonymousSurvey实例,并在每个方法中都创建了一个答案。setUp()方法可以让我们只创建这些对象一次,并在每个测试方法中使用它们。
import unittest from survey import AnonymousSurvey class TestAnonymousSurvey(unittest.TestCase): """针对AnonymousSurvey类的测试""" def setUp(self): """创建一个调查对象和一组答案,供使用的测试方法使用""" question = "What language did you first learn to speak?" self.my_survey = AnonymousSurvey(question) #创建一个调查对象 self.responses = ['English', 'python', 'C'] #创建一个答案列表,存储在属性中,有self def test_store_single_response(self): """测试单个答案会被妥善地存储""" self.my_survey.store_response(self.responses[0]) self.assertIn(self.responses[0], self.my_survey.responses) def test_store_three_responses(self): """测试三个答案会被妥善地存储""" for response in self.responses: self.my_survey.store_response(response) for response in self.responses: self.assertIn(response, self.my_survey.responses) unittest.main()
十七. matplotlib
win10安装matplotlib:pip install matplotlib
17.1 折线图
例1:绘制简单的折线
需要导入matplotlib模块里面的pyplot
import matplotlib.pyplot as plt squares = [1, 4, 9, 16, 25] plt.plot(squares) plt.show() # 打开matplotlib查看器,并显示绘制的图形
例2:修改标签文字和线条粗细
linewidth=5决定线的粗细
import matplotlib.pyplot as plt squares = [1, 4, 9, 16, 25] plt.plot(squares, linewidth=5) # linediwth决定了绘制线条的粗细 # 设置图表标题,并给坐标轴加上标签 plt.title("Square Numbers", fontsize=24) # title指明标题 plt.xlabel("Value", fontsize=14) plt.ylabel("Square of Value", fontsize=14) # 设置刻度标记的大小 plt.tick_params(axis='both', labelsize=14) # 设置刻度,刻度字号14 plt.show()
例3:设置x轴正确刻度,校正图形
import matplotlib.pyplot as plt input_values = [1, 2, 3, 4, 5] squares = [1, 4, 9, 16, 25] plt.plot(input_values, squares, linewidth=5) # linediwth决定了绘制线条的粗细 # 设置图表标题,并给坐标轴加上标签 plt.title("Square Numbers", fontsize=24) # title指明标题 plt.xlabel("Value", fontsize=14) plt.ylabel("Square of Value", fontsize=14) # 设置刻度标记的大小 plt.tick_params(axis='both', labelsize=14) # 设置刻度,刻度字号14 plt.show()
可见前后两图x轴不同了
17.2 散点图
例1:画一个点
import matplotlib.pyplot as plt plt.scatter(2, 4) plt.show()
例2:设置刻度坐标
import matplotlib.pyplot as plt plt.scatter(2, 4, s=200) # s为尺寸 # 设置图表标题并给坐标轴加上标签 plt.title("Square Number", fontsize=24) plt.xlabel("Value", fontsize=24) plt.ylabel("Square of Value", fontsize=24) # 设置刻度标记的大小 plt.tick_params(axis='both', which='major', labelsize=14) plt.show()
例3:绘制一系列点
import matplotlib.pyplot as plt x_values = [1, 2, 3, 4, 5] y_values = [1, 4, 9, 16, 25] plt.scatter(x_values, y_values, s=100) # s为尺寸 # 设置图表标题并给坐标轴加上标签 plt.title("Square Number", fontsize=24) plt.xlabel("Value", fontsize=24) plt.ylabel("Square of Value", fontsize=24) # 设置刻度标记的大小 plt.tick_params(axis='both', which='major', labelsize=14) plt.show()