python基础(字符编码、文件操作、深浅copy操作)
一、编码的进阶:
1.1 str与bytes区别:
1.1.1 英文:
str:
在内存中的编码:Uniode
表现形式:'taibai'
bytes:
在内存中的编码:非Unicode
表现形式:b'taibai'
1.1.2 中文:
str:
在内存中的编码:Uniode
表现形式:'中国'
bytes:
在内存中的编码:非Unicode
表现形式:b'\xe4\xb8\xad\xe5\x9b\xbd'
1.2 编码与解码范式:
1.2.1 编码实例:
1 # 编码: 2 s = 'alex' 3 s = '中国' 4 b = s.encode('gbk') # 一个中文用两个字节表示 5 print(b) 6 u1 = s.encode('utf-8') # 一个中文用三个字节表示 7 print(u1)
1.2.2 解码实例:
1 # 解码: 2 b = b'\xd6\xd0\xb9\xfa' # 中文编码为gbk解码必须用gbk,英文特殊字符除外 3 s = b.decode('gbk') 4 print(s) 5 6 u = b'\xe4\xb8\xad\xe5\x9b\xbd' # 中文编码为gbk解码必须用gbk,英文特殊字符除外 7 s = u.decode('utf-8') 8 print(s)
1.2.3 特殊方法:
1 # 终极解码: 2 u = b'\xe4\xb8\xad\xe5\x9b\xbd' 3 s = u.decode('utf-8') # 先解码为Unicode 4 print(s) 5 b = s.encode('gbk') # 再进行gblk编码 6 print(b) 7 8 # 特殊解码范式: 9 # 因为utf-8与gbk中,数字,字母,与特殊字符都遵循ASCII码规范,所以可以进行相互解码 10 # 但是中文字符串是每种编码方式不同(utf-8:3字节,gbk:2字节) 11 u = '123abc,.?' 12 s = u.encode('utf-8') # 先编码为utf-8 13 print(s) 14 b = s.decode('gbk') # 再进行gbk解码 15 print(b)
1.2.4 字符串与Bytes之间转换:
# 字符串转bytes方式一 str1='逆火' b=bytes(str1, encoding='utf-8') print(b) # bytes转字符串方式二 b=b'\xe9\x80\x86\xe7\x81\xab' string=b.decode() # 第一参数默认utf8,第二参数默认strict print(string)
二、文件操作命令:
2.1 文件句柄(f):
1 # 文件句柄的生成方式 2 # f 变量: f,f1,file,file_handler,fh,f_h..... 文件句柄 3 4 f1= open('test.txt', encoding='utf-8', mode='r') # 方式一 5 with open('test.txt', encoding='utf-8', mode='r') as f2: # 方式二
2.2 操作文件的流程:
打开文件,产生一个文件句柄.
对文件句柄进行相应的操作.
关闭文件句柄.
2.3 文件操作的常见问题:
路径问题:
绝对路径与相对路径
编码的问题:UnicodeDecodeError:
编码要与文件存储时的编码保持一致.
后缀名:
文件后缀名大小写与隐藏文件名等
2.4 文件读写操作:
2.4.1 文件的读(读模式下,mode='r'可以忽略不写):
四种模式:
r r+ rb r+b ...
2.4.2 文件读范式:
1 # 文件读取 2 # 申明的编码方式(encoding) 与指定编码/解码方式(encode/decode)不是同一个概念 3 # 方式一: 4 f = open('test.txt', encoding='utf-8', mode='r') # encoding 申明的编码方式 5 print(f.read()) # 一次性全部读取 6 f.close() 7 8 # 方式二: 9 f = open('test.txt', encoding='utf-8', mode='r') # encoding 申明的编码方式 10 print(f.readline()) # 读取一行文件 11 f.close() 12 13 # 方式三: 14 f = open('test.txt', encoding='utf-8', mode='r') # encoding 申明的编码方式 15 print(f.readlines()) # 每一行依次读取全部文件 16 f.close() 17 18 # 方式四: 19 f = open('test.txt', encoding='utf-8', mode='r') 20 for i in f: # for默认每次读取一行,避免操作大文件是内存过载 21 print(i) 22 f.close() 23 24 # 方式五: 25 # rb 以字节的形式读取 26 # 带b的一般操作的都是非文字类的文件(音频,图片,视频...) 27 f1 = open('美女.jpg',mode='rb') # rb方式读写文件不需要申明编码方式 28 print(f1.read()) 29 f1.close() 30 31 # 方式六: 32 # r+ 读写模式:先读后写 33 f1 = open('test.txt',encoding='utf-8',mode='r+') 34 content = f1.read() 35 print(content) 36 f1.write('666') 37 f1.close()
2.4.3 文件的写:
四种模式:
w w+ wb w+b
2.4.4 文件写范式:
1 # 文件写入: 2 # 没有文件,创建文件,写入内容 3 # 如果有文件,先清空内容,后写入 4 5 # 方式一: 6 f = open('test.txt', encoding='utf-8', mode='w') # 单行写入 7 f.write('这是一个文件写入操作') 8 f.close() 9 10 f = open('test.txt', encoding='utf-8', mode='w') # 多行写入 11 for i in range(10): 12 f.write('这是一个文件写入操作\n') 13 f.close() 14 15 # 方式二: 16 # wb方式 17 f = open('meinv.jpg', mode='rb') # bytes文件格式读入不需要指定编码格式 18 content = f.read() 19 f.close() 20 f = open('meinv1.jpg', mode='wb') # bytes文件格式写入不需要指定编码格式 21 f.write(content) 22 f.close()
2.4.5 文件的追加写入:
四种模式:
a ab a+ a+b
2.4.6 文件写范式:
1 # 文件追加方式范式: 2 # a 没有文件,创建文件,写入内容 3 4 f = open('a模式',encoding='utf-8',mode='a') 5 f.write('666') 6 f.close()
2.4.7 文件其他操作方法:
1 # 文件操作的几个常用方法: 2 3 # fileno()方法: 4 f1 = open('test.txt', encoding='utf-8') 5 print(f1.read()) 6 print(f1.fileno()) # 文件行数 7 f1.close() 8 9 # flush()方法: 10 f1 = open('test.txt', encoding='utf-8', mode='w') 11 f1.write('666') 12 f1.flush() # 强制保存 13 f1.close() 14 15 # readable()方法: 16 f1 = open('test.txt', encoding='utf-8') 17 print(f1.readable()) # 判断文件是否可读(True) 18 f1.write('666') 19 f1.close() 20 21 # writable()方法: 22 f1 = open('test.txt', encoding='utf-8', mode='w') 23 print(f1.writable()) # 判断文件是否可写(True) 24 if f1.writable(): 25 f1.write('666') 26 f1.close() 27 28 # seek()/tell()方法: # seek()方法: # seek(5) 移动光标的5字节位置 # seek(0, 0) 光标移动到头部 # seek(0, 1) 光标移动到当前位置 # seek(0, 2) 光标移动文件末尾 29 # 网络编程: FTP的作业,断点续传的功能. seek tell 30 f1 = open('test.txt', encoding='utf-8', mode='r') 31 # f1.seek(9) # 按照字节跳转至光标位置 32 print(f1.tell()) # 获取光标的位置 33 f1.close() 34 35 # truncate()方法: 36 # 注意:1)f.seek(3)调整光标对truncate不管用 2)truncate必须在可写情况下使用. 37 f1 = open('test.txt', encoding='utf-8', mode='r+') 38 f1.truncate(9) # 从文件的开始进行截取内容,以字节为单位. 39 f1.close()
2.4.8 文件操作的特殊范式:
1 # 文件操作特殊范式: 2 3 with open('test.txt', encoding='utf-8', mode='r') as f: 4 print(f.read()) 5 f.close() # 在读出后需要再做写操作时,必须先进行文件句柄进行关闭 6 with open('test.txt', encoding='utf-8', mode='w') as f1: 7 f1.write('hello Kitty')
2.4.9 文件的高级操作:
1 # 文件高级操作(模拟文件内存修改操作): 2 3 import os 4 with open('test.txt', encoding='utf-8') as f1,\ 5 open('test.sh', encoding='utf-8', mode='w') as f2: # with的句柄追加方式 6 for i in f1: 7 content = i.replace('hello', 'hhh') 8 f2.write(content) 9 10 os.remove('test.txt') 11 os.rename('test.sh', 'test.txt')
三、赋值与深浅copy:
3.1 赋值操作:
1 # 赋值运算 变量指向的是同一个内存地址: 2 # 赋值操作时,增加删除元素内存地址不变 3 4 5 l1 = [1, 2, 3, [11, 22]] 6 l2 = l1 # l1与l2标签指向同一内存地址 7 l2.append(666) # 列表直接增加元素 8 l2[-1].append(666) # 列表中可变二级列表增加元素 9 print(l1, l2) 10 print(l1[0], l2[0]) 11 print(l1[-1], l2[-1]) 12 print(id(l1), id(l2))
3.2 浅copy操作:
1 # 浅copy 列表举例 2 # 浅copy: 无论是同一个代码块,不同代码块下: 3 # 复制一个外壳(列表),新开一个内存内存空间,但是列表里面的所有元素,都共用一个. 4 5 l1 = [1, 2, 3, [11, 22]] 6 l2 = l1.copy() 7 l2.append(666) # 列表直接增加不可变元素,只改变l2列表 8 l2[-1].append(666) # 列表中增加二级可变列表,l1,l2列表改变 9 print(l1, l2) 10 print(id(l1[0]), id(l2[0])) # 同一内存地址 11 print(id(l1[-1]), id(l2[-1])) # 同一内存地址 12 print(id(l1), id(l2)) # 复制一个外壳(列表),新建内存地址
3.3 深copy操作:
1 # 深copy 2 # 不可变数据类型 共用一份 3 # 可变的数据类型 重新创建一份 4 5 import copy 6 l1 = [1, 2, 3, [11, 22]] 7 l2 = copy.deepcopy(l1) 8 l2.append(666) # 列表直接增加不可变元素,只改变l2列表 9 l2[-1].append(666) # 列表中增加二级可变列表,重新创建一份l2列表改变 10 print(l1, l2) 11 print(id(l1[0]), id(l2[0])) # 不可变数据类型,同一内存地址 12 print(id(l1[-1]), id(l2[-1])) # 可变的数据类型,不同内存地址 13 print(id(l1), id(l2)) # 重新开辟内存空间,地址改变