内容概要

利用python代码的编写来读写文件
1.文件的概念
2.文件的操作方式
3.文件读写模式
4.文件操作模式
5.文件诸多方法
6.文件内容修改
7.文件光标移动

今日内容详细

作业讲解

1.优化员工管理系统
  拔高: 是否可以换成字典或者数据的嵌套使用完成更加完善的员工管理而不是简简单单的一个用户名(能写就写不会没有关系)
  员工的信息有:用户名 年龄 岗位 薪资...
  员工管理系统:注册、查看(单个员工、所有员工)、修改薪资、删除员工
        
2.去重下列列表并保留数据值原来的顺序
	eg: [1,2,3,2,1] 去重之后 [1,2,3]
	l1 = [2,3,2,1,2,3,2,3,4,3,4,3,2,3,5,6,5]
    
3.有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合
  pythons={'jason','oscar','kevin','ricky','gangdan','biubiu'}
  linuxs={'kermit','tony','gangdan'}
  1. 求出即报名python又报名linux课程的学员名字集合
  2. 求出所有报名的学生名字集合
  3. 求出只报名python课程的学员名字
  4. 求出没有同时这两门课程的学员名字集合

4.统计列表中每个数据值出现的次数并组织成字典战士
	eg: l1 = ['jason','jason','kevin','oscar']
      结果:{'jason':2,'kevin':1,'oscar':1}
	真实数据
    	l1 = ['jason','jason','kevin','oscar','kevin','tony','kevin']
    
# 2.定义一个存储所有员工信息的字典
# user_data_dict = {}  # {'编号':用户字典, '编号':用户字典}
'''
数据存储的方式1
{
    'jason':[18, 'teacher', 10],
    'kevin':[28, 'sale', 90]
}
数据存储的方式2
{
    'jason':{'age':18, 'job':'teacher', 'salary':8000},
    'kevin':{'age':28, 'job':'sale', 'salary':9000}
}
数据存储的方式3
{
    '1':{'name':'jason','age':18, 'job':'teacher', 'salary':8000},
    '2':{'name':'kevin','age':28, 'job':'sale', 'salary':9000},
    '3':{'name':'jason','age':18, 'job':'teacher', 'salary':8000},
}
'''
# 1.先搭建系统骨架
# while True:
#     print("""
#     1.创建员工信息
#     2.查看单个员工
#     3.查看所有员工
#     4.修改员工薪资
#     5.删除员工信息
#     """)
#     choice = input('请选择您想要执行的功能编号>>>:').strip()
#     if choice == '1':
#         while True:
#             # 1.获取员工编号
#             emp_id = input('请输入该员工的员工编号(q)>>>:').strip()
#             if emp_id == 'q':
#                 break
#             # 判断编号是否是纯数字
#             if not emp_id.isdigit():
#                 print('员工编号必须是纯数字')
#                 continue
#             # 2.判断员工编号是否已存在
#             if emp_id in user_data_dict:
#                 print('员工编号已存在 请重新录入')
#                 continue
#             # 3.获取员工详细信息
#             username = input('请输入员工姓名>>>:').strip()
#             age = input('请输入员工年龄>>>:').strip()
#             job = input('请输入员工岗位>>>:').strip()
#             salary = input('请输入员工薪资>>>:').strip()
#             # 4.构建一个临时的小字典
#             temp_dict = {}
#             # 5.添加员工信息键值对
#             temp_dict['emp_id'] = emp_id
#             temp_dict['name'] = username
#             temp_dict['age'] = age
#             temp_dict['job'] = job
#             temp_dict['salary'] = salary
#             # 6.添加到大字典中
#             user_data_dict[emp_id] = temp_dict
#             print(f'员工{username}添加成功')
#     elif choice == '2':
#         while True:
#             # 1.先获取员工编号
#             target_id = input('请输入您想要查看的员工编号(q)>>>:').strip()
#             if target_id == 'q':
#                 break
#             # 2.判断员工编号是否不存在
#             if target_id not in user_data_dict:
#                 print('员工编号不存在 无法查看')
#                 continue
#             # 3.根据员工编号获取员工字典数据
#             user_dict = user_data_dict.get(target_id)
#             # 4.格式化输出
#             print(f"""
#             --------------info of emp-------------------
#             编号:{user_dict.get('emp_id')}
#             姓名:{user_dict.get('name')}
#             年龄:{user_dict.get('age')}
#             岗位:{user_dict.get('job')}
#             薪资:{user_dict.get('salary')}
#             --------------------------------------------
#             """)
#     elif choice == '3':
#         for user_dict in user_data_dict.values():
#             print(f"""
#             --------------info of emp-------------------
#             编号:{user_dict.get('emp_id')}
#             姓名:{user_dict.get('name')}
#             年龄:{user_dict.get('age')}
#             岗位:{user_dict.get('job')}
#             薪资:{user_dict.get('salary')}
#             --------------------------------------------
#             """)
#     elif choice == '4':
#         while True:
#             # 1.先获取想要修改的员工编号
#             target_id = input('请输入您想要修改的员工编号(q)>>>:').strip()
#             if target_id == 'q':
#                 break
#             if target_id not in user_data_dict:
#                 print('员工编号不存在')
#                 continue
#             # 2.获取新的薪资
#             new_salary = input('请输入该员工的新薪资待遇>>>:').strip()
#             if not new_salary.isdigit():
#                 print('薪资只能是纯数字')
#                 continue
#             # 3.获取员工字典
#             user_dict = user_data_dict.get(target_id)  # {'salary':123}
#             # 4.修改字典中的薪资
#             user_dict['salary'] = new_salary  # {'salary': 321}
#             # 5.修改大字典
#             user_data_dict[target_id] = user_dict
#             print(user_data_dict.get(target_id))
#     elif choice == '5':
#         while True:
#             # 1.先获取想要修改的员工编号
#             target_id = input('请输入您想要删除的员工编号(q)>>>:').strip()
#             if target_id == 'q':
#                 break
#             if target_id not in user_data_dict:
#                 print('员工编号不存在')
#                 continue
#             # 2.字典删除键值对
#             user_data_dict.pop(target_id)
#     else:
#         print('抱歉 暂无该功能编号!!!')


# 2.去重下列列表并保留数据值原来的顺序
# 	eg: [1,2,3,2,1] 去重之后 [1,2,3]
# l1 = [2, 3, 2, 1, 2, 3, 2, 3, 4, 3, 4, 3, 2, 3, 5, 6, 5]
# 不考虑顺序的情况下 去重
# s1 = set(l1)
# l2 = list(s1)
# print(l2)
# 考虑顺序
# new_list = []
# for i in l1:
#     if i not in new_list:
#         new_list.append(i)
# print(new_list)


# 3.有如下两个集合,pythons是报名python课程的学员名字集合,linuxs是报名linux课程的学员名字集合
#   pythons={'jason','oscar','kevin','ricky','gangdan','biubiu'}
#   linuxs={'kermit','tony','gangdan'}
#   1. 求出即报名python又报名linux课程的学员名字集合
#   2. 求出所有报名的学生名字集合
#   3. 求出只报名python课程的学员名字
#   4. 求出没有同时这两门课程的学员名字集合

# pythons = {'jason', 'oscar', 'kevin', 'ricky', 'gangdan', 'biubiu'}
# linuxs = {'kermit', 'tony', 'gangdan'}
# print(pythons & linuxs)
# print(pythons | linuxs)
# print(pythons - linuxs)
# print(pythons ^ linuxs)


# 4.统计列表中每个数据值出现的次数并组织成字典展示
# 	eg: l1 = ['jason','jason','kevin','oscar']
#       结果:{'jason':2,'kevin':1,'oscar':1}
# 	真实数据
l1 = ['jason', 'jason', 'kevin', 'oscar', 'kevin', 'tony', 'kevin']
# 1.先定义结果集空字典
data_dict = {}
# 2.循环列表中每一个数据值
for name in l1:  # 'jason'  'kevin'
    # 3.判断当前数据值是否在字典的k中
    if name not in data_dict:  # {'jason':1}
        data_dict[name] = 1
    else:
        data_dict[name] += 1
        # data_dict[name] = data_dict.get(name) + 1
print(data_dict)

文件操作

1.文件的概念
	就是操作系统暴露给用户操作硬盘的快捷方式	
 		eg:双击一个文件 其实是从硬盘将数据加载到内存
         ctrl+s保存文件 其实是将内存中的数据刷到硬盘保存
2.代码打开文件的两种方式
	方式1:
        f = open(文件路径,读写模式,encoding='utf8')
        f.close()
	方式2:
        with open('a.txt', 'r', encoding='utf8') as f1:
        	with子代码块
 	ps:with上下文管理好处在于子代码运行结束自动调用close方法关闭资源
"""
open方法的第一个参数是文件路径 并且撬棍跟一些字母的组合会产生特殊的含义导致路径查找混乱 为了解决该问题可以在字符串的路径前面加字母r
	D:\a\n\t
	r'D:\a\n\t'
以后涉及到路径的编写 推荐加上r

with支持一次性打开多个文件
	with open() as f1,open() as f2,open() as f3:
		子代码
"""

文件读写模式

'r'		只读模式:只能读不能写
 	 # 1.文件路径不存在:会直接报错
    # with open(r'b.txt','r',encoding='utf8') as f:
    #     print(f.read())
    # 2.文件路径存在:正常读取文件内容
    with open(r'a.txt', 'r', encoding='utf8') as f:
        print(f.read())
        
'w'		只写模式:只能写不能看
    # 1.文件路径不存在:自动创建
    # with open(r'b.txt', 'w', encoding='utf8') as f:
    #     pass
    # 2.文件路径存在:先清空文件内容 之后再写入
    with open(r'a.txt', 'w', encoding='utf8') as f:
        f.write('假期综合征 赶紧要调整\n')
        f.write('假期综合征 赶紧要调整\n')
        f.write('假期综合征 赶紧要调整\n')
    '''强调:换行符需要自己添加 并且在后续数据读取比对的时候也一定要注意它的存在'''
    
'a'		只追加模式:文件末尾添加数据
    # 1.文件路径不存在:自动创建
    # with open(r'c.txt', 'a', encoding='utf8') as f:
    #     pass
    # 2.文件路径存在:自动在末尾等待追加内容
    with open(r'a.txt', 'a', encoding='utf8') as f:
        f.write('放假七天和上班七天感觉是完全不一样的')
        
"""
当我们在编写代码的时候 有些部分不知道写什么具体代码 但是也不能空着不写
这个时候可以使用关键字
	pass
	...
只补全语法不执行功能 本身没有任何的含义
"""

文件操作模式

t	文本模式
	默认的模式 我们上面所写的r w a其实全称是 rt wt at
	1.只能操作文本文件
 	2.读写都是以字符为单位
  	3.需要指定encoding参数 如果不知道则会采用计算机默认的编码
    
b	二进制模式(bytes模式)
	不是默认的模式 需要自己指定 rb wb ab
 	1.可以操作任意类型的文件
 	2.读写都是以bytes为单位 读写都是二进制
 	3.不需要指定encoding参数 因为它已经是二进制模式了 不需要编码
 
二进制模式与文本模式针对文件路径是否存在的情况下 规律是一样的!!!

例:打开一个存在的文本文件
with open(r'a.txt', 'rb') as f:
    print(f.read())  # 输出的内容是byte数据类型,人看不懂
    print(f.read().decode('utf8'))  #解码一下,回到中文了
  
打开一个存在的mp4视频文件
with open(r'D:\...mp4','rb') as f:
   print(f.read())   # 输出的内容是byte数据类型,人看不懂.里面是视频或者其他什么,没办法直接在pycharm解压观看,要用视频软件才能解出来

将某视频资源拷贝一份到当前pycharm目录下(不用cv用代码)
with open(r'D:\...mp4', 'rb') as read_f, open (r'tv.mp4', 'wb')as write_f:
    write_f.write(read_f.read())  # 把D:\...mp4文件里的内容读出来,写进新的现创的tv.mp4文件里。把pycharm里面的TV.mp4文件拖到桌面上就是正常视频
    
with open(r'c.txt', 'rb') as f:
    f.write('哈哈哈天黑了')  # “哈哈哈天黑了”会飘底色,运行代码会报错。因为用的是bytes模式,所以要输入类似二进制的东西,不能是字符串
改写为: f.write('哈哈哈天黑了'.encode('utf8'))  # 把字符串转化为计算机能读懂的字符就可以。这样运行的结果是在c.txt里面写入了“哈哈哈天黑了”

with open(r'c.txt', wb) as f:
    f.write(b'hello world 666')
如果字符串里面是英文字母 数字,没有中文没有其他国家的字符,要把这字符串转成二进制有简便方法,可以在这个字符串前面加b

扩展 别的转二进制的方法:
res = '天黑了 要干饭了'
data = bytes(res,'utf8') # 等价于encode
print(data) # 手上字符串想转成bytes类型,就用bytes把它包起来,给它一个编码就可
ret = str(data,'utf8')  #等价于decode
print(ret)  # 天黑了 要干饭了
想转成什么数据类型就用什么数据类型把它包起来,再提供一个编码
    

文件诸多方法

1.read() 	
	一次性读取文件内容 并且光标停留在文件末尾 继续读取则没有内容
	并且当文件内容比较多的时候 该方法还可能会造成计算机内存溢出
 	括号内还可以填写数字 在文本模式下 表示读取几个字符 print(f.read(5))即读取前5个字符或者字节(一个英文1个字节,1个中文3个字节,数字1个字节)
2.for循环
for line in f:
    print(line)  # 有几行内容就循环几次展现在run
	一行行读取文件内容 避免内存溢出现象的产生
3.readline()
print(f.readline)  # 打1个print就run1行
	一次只读一行内容
4.readlines()
print(f.readlines)  # 以列表形式呈现,带换行符\n
	一次性读取文件内容 会按照行数组织成列表的一个个数据值
5.readable()
print(f.readable)  # 返回结果是True 或者False。用read模式打开,那就是True
	判断文件是否具备读数据的能力 
6.write()
	写入数据
7.writeable()
	判断文件是否具备写数据的能力
8.writelines()
	接收一个列表 一次性将列表中所有的数据值写入
9.flush()
	将内存中文件数据立刻刷到硬盘 等价于ctrl + s

文件内光标的移动

with open(r'a.txt', 'rb') as f:
    print(f.read())
    f.seek(0,0)
    print(f.read())
    f.seek(0, 0)
    print(f.read())
    # print(f.read(2).decode('utf8'))
    # f.seek(-1, 2)
    # print(f.tell())  # 返回光标距离文件开头产生的字节数
    """
    seek(offset, whence)
        offset是位移量 以字节为单位
        whence是模式   0  1  2
            0是基于文件开头
                文本和二进制模式都可以使用
            1是基于当前位置
                只有二进制模式可以使用
            2是基于文件末尾
                只有二进制模式可以使用
    """
    # print(f.read(3).decode('utf8'))