python文件操作、深浅copy
一、编码进阶
str:它在内存中的编码方式: Unicode
但是咱们写入文件的内容,传输给别人的数据,一般都是str的形式.
矛盾点:网络传输,数据存储到磁盘你用的0101010这种二进制,不能使用Unicode的编码本去编译.但是python3x又需要str形式去操作
利用str 发送或者传输
(转换,将unicode编码转化成非Unicode)
----> 发送,传输
- encode() 编码
- decode() 解码
二、文件的操作
#1. 打开文件,得到文件句柄并赋值给一个变量
f=open('a.txt','r',encoding='utf-8') #默认打开模式就为r
# f是文件操作句柄
#2. 通过句柄对文件进行操作
data=f.read()
#3. 关闭文件
f.close()
# whith 会自动关闭文件
with open('a.txt','w') as f:
pass
1.文件的读
1.r模式
r r+ rb r+b
- read() 全部读取
f1 = open('r模式',encoding='utf-8')
content = f1.read()
print(content,type(content))
f1.close()
- read(n)
r模式: n 字符
rb模式: n 字节
f1 = open('r模式',encoding='utf-8')
print(f1.read(3))
f1.close()
- readline() 按行读取
f1 = open('r模式',encoding='utf-8')
print(f1.readline().strip()) # 读取第一行
print(f1.readline().strip()) # 读取第二行
f1.close()
- readlines() 返回一个list 列表的每个元素是源文件的每一行
f1 = open('r模式',encoding='utf-8')
print(f1.readlines())
f1.close()
循环读取:使用文件操作句柄进行循环,防止文件过大,内存占用过大
f1 = open('r模式',encoding='utf-8')
for line in f1:
print(line)
f1.close()
2. rb 以字节的形式读取
带b的一般操作的都是非文字类的文件.
f1 = open('美女.jpg',mode='rb')
print(f1.read())
f1.close()
3.r+ 读写模式:先读后写
f1 = open('r模式',encoding='utf-8',mode='r+')
content = f1.read()
print(content)
f1.write('666')
f1.close()
注意是限度后写,如果先写会替换内容
2.文件的写
w w+ wb w+b
1.w
没有文件,创建文件,写入内容,如果有文件,先清空内容,后写入
f = open('w模式',encoding='utf-8',mode='w')
f.write('随便写一点')
f.close()
2.wb
以二进制的形式写入
f1 = open('美女.jpg',mode='rb')
content = f1.read()
f1.close()
f2 = open('美女1.jpg',mode='wb')
f2.write(content)
f2.close()
3.文件的追加
a ab a+ a+b
1.a
没有文件,创建文件,写入内容,存在文件,会在后面追加内容
f = open('a模式',encoding='utf-8',mode='a')
f.write('很多让人很有成就感的事情')
f.write('很多让人很有成就感的事情')
f.close()
4.文件的其他操作
def close(self, *args, **kwargs): # real signature unknown
关闭文件
pass
def fileno(self, *args, **kwargs): # real signature unknown
文件描述符
pass
def flush(self, *args, **kwargs): # real signature unknown
刷新文件内部缓冲区
pass
def isatty(self, *args, **kwargs): # real signature unknown
判断文件是否是同意tty设备
pass
def read(self, *args, **kwargs): # real signature unknown
读取指定字节数据
pass
def readable(self, *args, **kwargs): # real signature unknown
是否可读
pass
def readline(self, *args, **kwargs): # real signature unknown
仅读取一行数据
pass
def seek(self, *args, **kwargs): # real signature unknown
指定文件中指针位置
pass
def seekable(self, *args, **kwargs): # real signature unknown
指针是否可操作
pass
def tell(self, *args, **kwargs): # real signature unknown
获取指针位置
pass
def truncate(self, *args, **kwargs): # real signature unknown
截断数据,仅保留指定之前数据
pass
def writable(self, *args, **kwargs): # real signature unknown
是否可写
pass
def write(self, *args, **kwargs): # real signature unknown
写内容
pass
- seek有三种移动方式0,1,2,其中1和2必须在b模式下进行,但无论哪种模式,都是以bytes为单位移动的
- truncate是截断文件,所以文件的打开方式必须可写,但是不能用w或w+等方式打开,因为那样直接清空文件了,所以truncate要在r+或a或a+等模式下测试效果。
5.文件的改
1.方式一
将硬盘存放的该文件的内容全部加载到内存,在内存中是可以修改的,修改完毕后,再由内存覆盖到硬盘(word,vim,nodpad++等编辑器)
2.方式二
将硬盘存放的该文件的内容一行一行地读入内存,修改完毕就写入新文件,最后用新文件覆盖源文件
# 1,以读的模式打开原文件.
# 2,以写的模式创建一个新文件.
import os
with open('aa自述',encoding='utf-8') as f1,\ # \ 代码换行符,解释器会认为一行
open('aa自述.bak',encoding='utf-8',mode='w') as f2:
# 3,将原文件内容读取出来,按照你的要求改成新内容,写入新文件.
for old_line in f1:
new_line = old_line.replace('aa','sb')
f2.write(new_line)
# 4,删除原文件.
os.remove('aa自述')
# 5,将新文件重命名成原文件.
os.rename('aa自述.bak','aa自述')
三、深浅copy
1.浅拷贝copy
#同一代码块下:
l1 = [1, '泰山', True, (1,2,3), [22, 33]]
l2 = l1.copy() # l2 = l1[:] 也是浅copy
print(id(l1), id(l2)) # 2713214468360 2713214524680
print(id(l1[-2]), id(l2[-2])) # 2547618888008 2547618888008
print(id(l1[-1]),id(l2[-1])) # 2547620322952 2547620322952
# 不同代码块下:
>>> l1 = [1, '泰山', True, (1, 2, 3), [22, 33]]
>>> l2 = l1.copy()
>>> print(id(l1), id(l2))
1477183162120 1477183162696
>>> print(id(l1[-2]), id(l2[-2]))
1477181814032 1477181814032
>>> print(id(l1[-1]), id(l2[-1]))
1477183162504 1477183162504
对于浅copy来说,只是在内存中重新创建了开辟了一个空间存放一个新列表,但是新列表中的元素与原列表中的元素是公用的。
2.深拷贝deepcopy
# 同一代码块下
import copy
l1 = [1, 'alex', True, (1,2,3), [22, 33]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2)) # 2788324482440 2788324483016
print(id(l1[0]),id(l2[0])) # 1470562768 1470562768
print(id(l1[-1]),id(l2[-1])) # 2788324482632 2788324482696
print(id(l1[-2]),id(l2[-2])) # 2788323047752 2788323047752
# 不同代码块下
>>> import copy
>>> l1 = [1, '泰山', True, (1, 2, 3), [22, 33]]
>>> l2 = copy.deepcopy(l1)
>>> print(id(l1), id(l2))
1477183162824 1477183162632
>>> print(id(0), id(0))
1470562736 1470562736
>>> print(id(-2), id(-2))
1470562672 1470562672
>>> print(id(l1[-1]), id(l2[-1]))
1477183162120 1477183162312
对于深copy来说,列表是在内存中重新创建的,列表中可变的数据类型是重新创建的,列表中的不可变的数据类型是公用的