day09

发布时间 2023-12-05 19:00:12作者: 王苗鲁

1.今日内容介绍

今日内容:
    1.字符编码(******) 
    
    2.文件处理的高级部分
        (1) 文件处理的其他方法
        (2) 控制文件指针移动
        (3) 文件修改的两种方式

    3.函数的基本使用
        函数名
        参数
        函数体代码
        函数的返回值

2.字符编码储备知识

文本编辑器读取python文件内容也经历了三个步骤
"""
1.先启动文本编辑器。
2.文本编辑器会发送系统调用,把test.py的内容从硬盘读入内存。
3.文本编辑器会将刚刚读入内存的内容控制输出到屏幕上,让用户看到结果。
"""

3.字符编码

1.人类的字符到计算机的数字必须经历一个过程
字符(就是语言)==>翻译==>数字

2.什么是字符编码表?
"""
字符与数字的对应关系表 
"""

x = '王苗鲁'
res = x.encode('utf-8')
print(res)

4.字符编码发展史

ASCII表
    1.只支持英文字符
    2.采用8位二进制对应一个英文字符

GBK表:
    1.支持英文字符、中文字符
    2.采用8位(8bit=1Bytes)二进制数对应一个英文字符串
      采用16位(16bit=2Bytes)二进制数对应一个中文字符串

unicode:(内存中统一使用unicode)
    1.兼容万国字符
    2.采用16位(16bit=2Bytes)二进制数对应一个中文字符串
    个别生僻字会采用4Bytes,8Bytes
    
    unicode表:                     内存
        人类的字符----------------unicode格式的数字-------
                                    |                 |
                                    |                 |
                                    |                 |
                                   硬盘                |
                                    |                 |
                                    |                 |
                               GBK格式的二进制      shift_JIS格式的二进制

          老的字符编码都可以转成unicode,但是不能通过unicode互转
          
utf-8:就是unicode的转换格式
    英文->1Bytes 
    中文->3Bytes 

1.内存固定使用unicode,我们可以改变的是存入硬盘采用格式
	 英文+汉字=>unicode=>gbk
     英文+日文=>unicode=>shift-jis
     万国字符 =>unicode=>utf-8

5.文本编辑器关于字符编码的应用

2.文本文件存取乱码问题
	 存乱了:文件的编码格式支持存入硬盘采用的格式.
     取乱了:文件以什么编码格式存入硬盘的,就应该以什么方式读入内存.

6.前两个阶段乱码问题解决方案

3.python解释器默认读文件的编码
	python3默认:utf-8
	python2默认:ASCII
	
	指定文件头修改默认的编码
	在py文件的首行写:
		# coding:utf-8 意思是用我告诉你的编码读文件

4.保证运行python程序的前两个阶段不乱码的核心法则:
	指定文件头
	# coding:文件当初存入硬盘时所采用的编码格式
	
	文本编辑器读取python文件内容也经历了三个步骤
	a.先启动文本编辑器。 # 第一个阶段
	b.文本编辑器会发送系统调用,把test.py的内容从硬盘读入内存。 # 第二个阶段
	
	第一阶段:用默认的编码
	第二阶段:# coding:utf-8 意思是用我告诉你的编码读文件

7.第三个阶段不乱码

5.python3的str类型默认直接存成unicode格式,无论如何不会乱码
	保证python2的str类型不乱码
		x=u'上'

8.编码与解码

x = '上'
print([x,])
#             编码                     编码
# 字符-------------------->unicode------------->其他编码

#             解码                      解码
# 字符<--------------------unicode<-------------其他编码

# print(x)
# res = x.encode("gbk")
# print(type(res))

# 强调:在python3里,只会将unicode格式的数字转成字符,其余编码格式的数字均不会转换
# print(res)
# print(res.decode("gbk"))


res = x.encode('gbk')  # unicode==>gbk unicode转成其他格式的编码称为编码

print(res.decode('gbk')) # 其他格式的编码转成unicode称之为解码

9.文件操作的其他方法

# # 一:读相关操作
# # 1.readline:一次读一行
# with open(r'g.txt', mode='rt', encoding='utf-8') as f:
#     # res1 = f.readline()
#     # res2 = f.readline()
#     # print(res1)
#     # print(res2)
#
#     while True:
#         line = f.readline()
#         if len(line) == 0:
#             break
#         print(line)

# # 2.readlines:把文件所有的内容读出来然后放到一个列表里面
# with open(r'g.txt', mode='rt', encoding='utf-8') as f:
#     res = f.readlines()
#     print(res)

# 强调:
# f.read()与f.readlines()都是将内容一次性读入内存,如果内容过大会导致内存溢出,若还想将内容全部读入内存,则必须分多次读入,有两种实现方式

# # 二:写相关操作
# # f.writelines():
# with open('h.txt', mode='wt', encoding='utf-8') as f:
#     # f.write('111\n222\n333\n')
#     # 必须是字符串不是数字
#     # l = ['111\n', '222', '3333',444]
#     l = ['111\n', '222', '3333']
#     # for line in l:
#     #     f.write(line)
#     # 这就是f.writelines(l)
#     f.writelines(l) 

with open('h.txt', mode='wb') as f:
    # l = ['111\n'.encode('utf-8'),
    #      '222'.encode('utf-8'),
    #      '333'.encode('utf-8')
    #      ]
    
    # # 补充1:如果是纯英文字符,可以直接加前缀b得到bytes类型
    # l=[b'111aaa\n',
    #    b'2222b2',
    #    b'333'
    #    ]

    # 补充2:'上'.encode('utf-8') 等同于bytes('上',encoding='utf-8')
    l = [bytes('上啊', encoding='utf-8'),
         bytes('冲呀', encoding='utf-8'),
         bytes('小垃圾们', encoding='utf-8'),
         ]
    f.writelines(l)
    

# # 3.flush:
# with open('h.txt', mode='wt', encoding='utf-8') as f:
#     f.write('哈')
#     # f.flush()
# 
# # 4.了解
# with open('h.txt', mode='wt', encoding='utf-8') as f:
#     print(f.readable())
#     print(f.writable())
#     print(f.encoding)
#     print(f.name)
# 
# # 判断文件是否关闭
# print(f.closed)

10.主动控制文件指针移动

# 指针移动的单位都是以bytes/字节为单位
# 只有一种情况特殊
#         t模式下的read(n),n代表的是字符个数,除此以外都是字节个数

with open('a.txt', mode='rt', encoding='utf-8') as f:
    res = f.read(6)  # 读出6个字符
    print(res)

with open('a.txt', mode='rb') as f:
    res = f.read(8)	# 读出8个字节,6个字节会报错
    print(res.decode('utf-8'))    
    
# 主动控制文件指针移动
# 0模式: 参照文件开头移动n个字节
# f.seek(3,0)
# f.seek(6,0)

# 1模式: 参照当前所在的位置移动n个字节
# f.seek(3,1)
# f.seek(6,1)

# 2模式: 参照文件末尾置移动n个字节
# f.seek(-3,2)
# f.seek(-6,2)

# ps: 只有0模式可以在t下使用,1和2模式都只能在b下使用

a.txt

hello你好

11.主动控制文件指针移动应用

0模式

 with open('a.txt', mode='rb') as f:
    # f.seek(3, 0)
    # f.seek(6, 0)
    # print(f.tell())

1模式

 with open('a.txt', mode='rb') as f:
	f.seek(3, 1)
    f.seek(6, 1)
    print(f.tell())

2模式

with open('a.txt', mode='rb') as f:
    # f.seek(0,2)
    # f.seek(-1,2)
    # print(f.tell())

    # f.seek(6,1)
    # data=f.read()
    # print(len(data))

    f.seek(-3, 2)
    data = f.read()
    print(data.decode('utf-8'))

12.动态监测文件追加内容(f.seek的应用)

soft.py

# tail -f access.log

import time

with open('access.log',mode='at',encoding='utf-8') as f:
    f.write("%s %s\n" %(time.strftime('%Y-%m-%d %H:%M:%S'),"egon给lxx转了10个亿"))

tail.py

import time

with open('access.log',mode='rb') as f:
    f.seek(0,2) # 指针跳到末尾

    while True:
        line = f.readline()
        if len(line) == 0:
            time.sleep(0.1) # 不要过多的消耗cpu资源
        else:
            print(line.decode('utf-8'),end='')

13.截断文件

a.txt

hello你好

test.py

with open('a.txt', mode='at', encoding='utf-8') as f:
    f.truncate(6)  # 截断的是6个字节

14.修改文件的两种方式

user.txt

王苗鲁     男       18      18917127096
熊慧君     女       28      13564332603
吴天雄     男       38      13901811370

两种修改方式

# 修改方式一
# 1.先把文件内容全部读入内存
# 2.然后在内存中完成修改
# 3.再把修改后的结果覆盖写入原文件
# 缺点:会在文件内容过大的情况下,占用过多的内存

with open('user.txt', mode='r', encoding='utf-8') as f:
    data = f.read()
    data = data.replace('王苗鲁', '吴佩其[老男孩第二帅的人]')

with open('user.txt', mode='w', encoding='utf-8') as f:
    f.write(data)



# 修改方式二
# 以读的方式打开原文件,以写的方式打开一个新文件
import os

with open('user.txt', mode='rt', encoding='utf-8') as read_f, \
        open('user.txt.swap', mode='wt', encoding='utf-8') as write_f:
    for line in read_f:
        if '吴佩其' in line:
            line = line.replace('吴佩其', '吴佩其[老男汉特别特别的老]')

        write_f.write(line)

os.remove('user.txt')
os.rename('user.txt.swap', 'user.txt')