>[success] # Python -- 文件的读写
~~~
1.一个运行中的程序会存取放在随机存取存储器(RAM)上的数据。RAM 读
取速度快,但 价格昂贵,需要持续供电,断电后保存在上面的数据会自动消
失。磁盘速度比 RAM 慢, 但容量大、费用低廉并且多次插拔电源线仍可保
持数据。因此,计算机系统在数据存储设 计中做出很大的努力来权衡磁盘和
RAM。程序员需要在非易失性介质(例如磁盘)上做 持久化存储和检索数
据。
2.因此整个读写操作相当于是在ram 执行的,使用的是ram内存条中的内存,
通俗的说是在一个文件 名下的字节流,把数据从一个文件读入内存,然后从
内存写入文件。
~~~
>[danger] ##### 常见的读写模式
~~~
1.了解读写的文件分两种,一种是普通文本文件,一种是二进制文件(图片,
音乐等),因此在python中,也分这两种模式,t(或者省略)代表文本类
型; b 代表二进制文件。
2. 只读(r, rb)
3. 只写(w, wb)
4. 追加(a, ab)
5. r+读写
6. w+写读
7. a+写读(追加写读)
~~~
>[danger] ##### 使用open -- 进行读写操作
~~~
1.open(filename,mode,encoding)中常用的三个参数 ,第一个filename是文件
名称,mode使用的读写模式,encoding 进行编码解码
2.在操作文件读写后需要关闭句柄,也就是close 操作
~~~
>[danger] ##### read -- (r,rb) 只读模式
~~~
1.r是rt 模式的缩写,是读取文本类的,rb是读取二进制类的例如图片
2.使用 read() 函数一次读入文件的所有内容。但在 读入文件时要格外注意,
1GB 的文件会用到相同大小的内存。因此会有更好的优化方案见案例
3.rb读取出来的数据是bytes类型, 在rb模式下. 不能选择encoding字符集.
4.read(n) 读取n个字符. 需要注意的是. 如果再次读取. 那么会在当前位置继
续去读⽽而不 是从头读, 如果使⽤用的是rb模式. 则读取出来的是n个字节
~~~
* 案例 普通的读写案例
~~~
f = open('../file/test', 'r', encoding='utf-8')
s = f.read() #read 是当前对象的一个方法,读出这个对象内的内容
print(s)
~~~
* 优化 读多少拿多少
~~~
f = open('../file/test', 'r', encoding='utf-8')
content = '' # 记录所有内容
chunk = 50 # 一次读取多少个字符
while True:
s = f.read(chunk)
if not s:
break
content += s
print(content)
~~~
>[danger] ##### write -- (w, wb) 写模式存在则删除
~~~
1.写的时候注意. 如果没有⽂文件. 则会创建⽂文件, 如果⽂文件存在. 则将原
件中原来的内容删除, 再 写入新内容
2.在写的时候注意两个好习惯一个是刷新,一个是关闭 f.flush() /f.close()
3.这是只写模式,不能进行读的操作
~~~
* 写入案例 -- write篇章
~~~
content = '写入的新的内容'
f = open('../file/test', 'w', encoding='utf-8')
f.write(content)
f.flush()
f.close()
~~~
* 写入案例 -- 万能print
~~~
# print 因为自带换行符,因此在使用的时候要考虑去掉默认的换行符
content = '写入的新的内容'
f = open('../file/test', 'w', encoding='utf-8')
print(content, file=f, sep='', end='')
f.close()
~~~
* 优化 写多少存多少
~~~
content = '写入的新的内容'
offset = 0
chunk = 2 # 一次写入多少
f = open('../file/test', 'w', encoding='utf-8')
while len(content) > offset:
f.write(content[offset:offset+chunk])
offset += chunk
f.close()
~~~
* 二进制写入
wb模式下. 可以不指定打开⽂文件的编码. 但是在写⽂文件的时候必须将字符串串转化成utf-8的 bytes数据
~~~
f = open("⼩小娃娃", mode="wb")
f.write("⾦金金⽑毛狮王".encode("utf-8"))
f.flush()
f.close()
~~~
>[danger] ##### 追加(a, ab) -- 在末尾追加
~~~
1.在追加模式下. 我们写入的内容会追加在⽂文件的结尾,必须文件存在
~~~
* 案例
~~~
f = open('../file/test', 'a', encoding='utf-8')
f.write("追加内容")
f.flush()
f.close()
~~~
>[danger] ##### r+ /r+b -- 读写模式
~~~
1.对于读写模式. 必须是先读. 因为默认光标是在开头的. 准备读取的. 当读完
了之后再进⾏行行 写入. 使⽤频率最⾼高的模式就是r+
2..在没有任何操作之前进行写. 在开头写
3. 如果读取了一些内容. 再写, 写入的是最后,也就是说read(1)执行了虽然
是读一个字符,但追加的内容也会在整个文章最后
~~~
* 必须是先读取. 然后再写入
~~~
f = open("⼩小娃娃", mode="r+", encoding="utf-8")
content = f.read()
f.write("麻花藤的最爱")
print(content)
f.flush()
f.close()
~~~
* 如果先写后读就会出现,追加的内容在,开头而不是在结尾,错误示范如下:
~~~
f = open("⼩小娃娃", mode="r+", encoding="utf-8")
f.write("哈哈") content = f.read()
print(content)
f.flush()
f.close()
结果: 将开头的内容改写成了了"哈哈", 然后读取的内容是后⾯面的内容.
~~~
>[danger] ##### readline() / readlines() -- 以行为单位读
~~~
1.readline() 和 .readlines() 之间的差异是后者一次读取整个文件
2.readline() 每次只读取一行,通常比 .readlines() 慢得多。仅当没有足够内存可以一次读取整个文件时,才应该使用 .readline()。
~~~
* 案例 -- 直接常用写法
~~~
f = open("吃的", mode="r", encoding="utf-8")
for line in f: # 每次读取一行. 赋值给前面的line变量
print(line)
f.close()
~~~
* 性能 读法
~~~
poem = ''
fin = open('relativity', 'rt' )
while True:
line = fin.readline()
if not line:
break
poem += line
fin.close()
~~~
>[danger] ##### w+/w+b -- 写读
~~~
1. 先将所有的内容清空. 然后写入. 最后读取. 但是读取的内容是空的, 不常⽤
2. 一开始读取不到数据. 然后写的时候再将原来的内容清空,不常用
~~~
* 案例
~~~
f = open("⼩小娃娃", mode="w+", encoding="utf-8")
f.write("哈哈")
content = f.read()
print(content)
f.flush()
f.close()
~~~
>[danger] ##### 追加读(a+)
~~~
1.啥用没有,a+模式下, 不论先读还是后读. 都是读取不到数据的.
~~~
~~~
f = open('../file/test', 'a+', encoding='utf-8')
f.write("追加内容")
s = f.read()
print(s)
~~~
>[danger] ##### seek(n) -- 光标移动
~~~
1. seek(n) 光标移动到n位置, 注意, 移动的单位是byte. 所以如果是UTF-8的
中⽂文部分要 是3的倍数. 三个字节构成一个字符
2. 移动到开头: seek(0),移动到结尾: seek(0,2) seek的第⼆二个参数表
⽰示的是从哪个位置进⾏行行偏移, 默认是0, 表 ⽰示开头, 1表⽰示当前位
置, 2表⽰示结尾
~~~
* 案例
~~~
f = open("⼩小娃娃", mode="r+", encoding="utf-8")
f.seek(0) # 光标移动到开头
content = f.read() # 读取内容, 此时光标移动到结尾
print(content) f.seek(0) # 再次将光标移动到开头
f.seek(0, 2) # 将光标移动到结尾
content2 = f.read() # 读取内容. 什什么都没有
print(content2) f.seek(0) # 移动到开头
f.write("张国荣") # 写⼊入信息. 此时光标在9 中⽂文3 * 3个 = 9
f.flush()
f.close()
~~~
>[danger] ##### 使用with自动关闭文件
~~~
1.如果你忘记关闭已经打开的一个文件, 在该文件对象不再被引用之后
Python 会关掉此文 件。这也就意味着在一个函数中打开文件,没有及时关
闭它,但是在函数结束时会被关 掉。然而你可能会在一直运行中的函数或
者程序的主要部分打开一个文件,应该强制剩下 的所有写操作完成后再关
闭文件。
Python 的上下文管理器(context manager)会清理一些资源,例如打开的文件。它的形式 为 with expression as variable:
with open('relativity', 'wt') as fout: ... fout.write(poem) ...
完成上下文管理器的代码后,文件会被自动关闭。
~~~
>[danger] ##### 修改文件内容
* 先读在写写的文件,删除读的,重命名写的
~~~
import os
with open("吃的", mode="r", encoding="utf-8") as f1, \
open("吃的_副本", mode="w", encoding="utf-8") as f2:
for line in f1:
s = line.replace("菜", "肉")
f2.write(s)
os.remove("吃的") # 删除文件
os.rename("吃的_副本", "吃的") # 重命名文件
~~~
>[danger] ##### 整合模式
~~~
1.使用with
2.使用for 循环
~~~
- PYTHON-- 基础
- Python -- 变量、常量、注解
- 算数\比较\赋值\逻辑运算符
- Python -- input 控制台用户输入
- Python -- 流程控制/循环语句
- Python -- 切片
- Python -- 数据类型
- 基础数据类型
- int -- 数字类型
- str -- 字符类型
- bool -- 布尔类型
- list -- 列表
- type -- 元祖
- dict -- 字典
- set -- 集合
- Python -- 深浅copy
- Python -- 文件的读写
- Python -- 函数
- 函数 -- 做参数使用
- 函数 -- 闭包
- 函数 -- 生成器
- 函数 -- 列表推导式
- 案例
- 基础案例一
- 基础案例二
- 基础案例三
- COOKBOOK
- LIST、STR、DICT、TUPLE
- LIST - 列表方法总结
- 一、序列拆分成单独变量
- 二、* 妙用
- 三、deque- 双向队列
- 四、求找到最大或最小的N个元素
- 4.1 heapq-- 简单使用
- 五、去重并保持列表顺序不变
- 六、切片slice
- 七、counter 统计序列中元素次数
- 八、itemgetter 列表套着字典排序
- 九、处理大量的列表数据
- 十、随机事件处理列表
- DICT - 字典的总结方法
- 一、defaultdict 解决 KeyError
- 二、OrdereDict有序字典
- 三、zip 和 max/min 比较
- IDCT和LIST- 推导式
- 一、LIST 推导式
- 二、字典推到式
- TUPLE-元组
- 一、命名元组
- STR-字符串
- 一、常见的字符串方法
- 二、字符串拆分
- 三、字符串的位置匹配
- 四、字符串替换
- 五、正则大小写/换行匹配
- 六、对字节类型处理
- 数字、日期、时间处理
- 一、数字的处理
- 二、时间换算
- 2.1 时间运算
- 2.2计算某一时刻上周几的日期
- 2.2对时间转换格式优化
- 迭代器和生成器
- 一、iter 迭代器 使用案例
- 二、生成器 yeild
- 三、构建一个反向迭代方法
- 四、实现反正函数构造
- 五、迭代对象切片/跳过元素
- 六、迭代出所有的组合排列
- 七、索引-值迭代序列化
- 八、zip 同时迭代多个序列
- 九、同时循环多个可迭代对象
- 十、yield from 递归案例
- 十一、合并序列,并按顺序输出
- 十二、使用 iter 替代 while True
- 操作文件
- 一、处理文件路径
- 二、检测文件/获取文件信息
- 函数
- 一、函数基本案例使用
- 二、匿名函数
- 三、回调函数
- 四、闭包实现一个单个方法类
- 五、函数嵌套回调函数
- 类与对象
- 一、str/repr--让类字符串表示
- 二、format -- 格式化类的内容
- 三、with -- 上下文管理类
- 四、创建节省内存的类
- 五、将类里面方法变成属性
- 六、调用父类方法
- 七、扩展子类中的属性
- 八、创建新的类或者实类属性
- 九、简化数据结果,简化init
- 十、python 接口写法
- 十一、通过类属性创建委托访问
- 十二、__new__重新初始化init
- 十三、通过字符串调用类
- 元编程
- 一、装饰器
- 1.1 去掉装饰器修饰
- 1.2 可接受参数装饰器
- 1.3利用装饰器对函数参数类型检查
- 1.4编写类装饰器
- 1.5为类方法和静态方法加装饰器
- 1.6通过装饰器给装饰函数加参数
- 线程和进程