1. os.path的方法
impot os # os.path.abspath 返回path规范化的绝对路径 # (1)把路径中不符合规范的/改成改成操作系统默认的格式 path = os.path.abspath('D:/pythonproject/day19/03 os.path方法.py') print(path) # D:\pythonproject\day19\03 os.path方法.py # (2)能够给能找到的相对路径改成绝对路径 path = os.path.abspath('03 os.path方法.py') print(path) # D:\pythonproject\day19\03 os.path方法.py # 如果你两个值都需要 os.path.split # 如果你只要第一个/第二个 os.path.dirname/os.path.basename # os.path.split 就是把一个路径分成两段返回一个元组,第二段是一个文件/文件夹 # windows'\\' linux'/' 都认识,都能分割 path = os.path.split('D:/pythonproject/day19/03 os.path方法.py') print(path) # ('D:/pythonproject/day19', '03 os.path方法.py') path = os.path.split('D:/pythonproject/day19') print(path) # ('D:/pythonproject', 'day19') # os.path.dirname 取第一个的值 ret1 = os.path.dirname('D:/pythonproject/day19/03 os.path方法.py') print(ret1) # D:/pythonproject/day19 # os.path.basename 取第二个值 ret2 = os.path.basename('D:/pythonproject/day19/03 os.path方法.py') print(ret2) # 03 os.path方法.py # 判断文件/文件夹是否存在 Ture/False res = os.path.exists(r'D:\pythonproject\day19\03 os.path方法.py') print(res) # 判断是否是绝对路径 Ture/False res1 = os.path.isabs('03 os.path方法.py') res2 = os.path.isabs(r'D:\pythonproject\day19\03 os.path方法.py') print(res1) # False print(res2) # True # 判断是否是文件 print(os.path.isfile(r'D:\pythonproject\day19\03 os.path方法.py')) # 判断是否是文件夹 print(os.path.isdir(r'D:\pythonproject\day19\03 os.path方法.py')) # 拼接路径(不管存在不存在,只管拼) path = os.path.join('D:/pythonproject/day19', '03 os.path方法.py') print(path) # os.path.getatime(path) 返回path所指向的文件或者目录的最后访问时间 # os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 # 查看文件大小(单位字节) size = os.path.getsize(r'D:\pythonproject\day19\03 os.path方法.py') print(size) # 5071 ret1 = os.path.getsize('D:\pythonproject\day19') ret2 = os.path.getsize('D:\pythonproject\day18') ret3 = os.path.getsize('D:\pythonproject\day17') print(ret1, ret2, ret3) # 4096 4096 4096 # windows所有的文件夹 都至少是4096个字节 # 还有可能是 8192 # mac上 64字节 + 32字节/新文件
#练习题 # 使用python代码统计一个文件夹中的所有文件的总大小 # 你需要统计文件夹大小 # D:\pythonproject\day17\ 文件夹的大小 # 拿到这个文件夹下所有的文件夹 和 文件 # 是文件就取大小 # 是文件夹 再打开这个文件夹: 文件/文件夹 # 递归 def func(path): # 'D:\pythonproject' size_sum = 0 name_list = os.listdir(path) for name in name_list: path_abs = os.path.join(path, name) if os.path.isdir(path_abs): size = func(path_abs) size_sum += size else: size_sum += os.path.getsize(path_abs) return size_sum ret = func('D:\pythonproject') print(ret) 注意: 我们统计windows上的文件夹大小有微弱的出入 因为windows上会有文件碎片 # 循环 # 堆栈思想 # 列表 满足一个顺序 先进来的后出去 lst = [r'D:\pythonproject'] size_sum = 0 while lst: # [r'D:\pythonproject'] lst = ['D:\pythonproject\day01','D:\pythonproject\day02',...] path = lst.pop() # path = 'D:\pythonproject' lst = [] path_list = os.listdir(path) # path_list = ['day01','day01',...aaa.py] for name in path_list: # name = day01 abs_path = os.path.join(path, name) # 拼接成绝对路径 if os.path.isdir(abs_path): # 文件夹的逻辑 lst.append(abs_path) # lst.append('D:\pythonproject\day01') lst=['D:\pythonproject\day01'] else: # 文件的逻辑 size_sum += os.path.getsize(abs_path) print(size_sum)
2. os精讲
# os.system("bash command") 运行shell命令,直接显示 # os.popen("bash command).read() 运行shell命令,获取执行结果 # os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 # os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd import os # 统计文件的大小 os.path.getsize('路径') # python的命令 dir 路径 \C # 操作系统的命令 # 帮助你显示当前路径下的所有文件和文件夹 os.system('dir 路径') # 使用python语言直接执行操作系统的命令 os.listdir('路径') # 使用python的os模块提供的方法 间接调用了操作系统命令 # 程序员 python开发 # 和python代码打交道 # 学习python的人 # web开发 # 运维开发 : 运维功底 熟悉操作系统命令 # 爬虫 # 人工智能 # exec('字符串数据类型的python代码') # eval('执行字符串数据类型的python代码') # # os.system('执行字符串数据类型的操作系统命令') # os.popen('执行字符串数据类型的操作系统命令,并返回结果') # chdir # 获取当前执行命令的时候所在的目录 # getcwd # 修改当前执行命令的时候所在的目录 ret = os.listdir('D:\pythonproject') print(ret) print(os.getcwd()) os.chdir('D:\pythonproject') print(os.popen('dir').read()) # os模块所做的事情 # 定制了很多方法 间接的帮助你去调用操作系统的命令 获得结果 # 然后帮助你分析整理成我们需要的数据类型的形态 # 你也可以os.popen/os.system直接去调用操作系统的命令 获得结果 # 但是 分析和整理的工作需要你自己做 # 用os模块的方法本身能够完成的功能我们用定制好的方法就够了 # 如果有一天 你发现os模块定制好的功能解决不了我们的问题了 # 而刚好操作系统的命令能够很好的帮助我们解决问题 # 这个时候就用os.popen/os.system
3. 序列化模块
1.什么是序列化?为什么要学序列化? # python # 序列化: 字符串 bytes # 序列: 列表 元组 字符串 bytes # 序列化的过程: 把其他的数据类型 转换成 字符串 bytes # str dic = {'1': '2'} print([str({'1': '2'}), dic]) # ["{'1': '2'}", {'1': '2'}] print([str([1, 2, 3]), [1, 2, 3]]) # ['[1, 2, 3]', [1, 2, 3]] # 为什么要把其他数据类型转换成字符串??? # (1)能够在网络上传输的只能是bytes, # (2)能够存储在文件里的只有bytes和str. # 处理文档里的字符串非常繁琐,而字典可以直接通过key取value dic = {'小明': {'pohone_num': 12346542856}, } ''' 小明|电话|性别 小张|... ''' # 字典 -> 字符串 -> 通过网络取传输 -> 字符串 -> 字典 # 转字符串的过程 不就是数据类型的强制转换吗? 为什么要序列化模块? # 字符串 -> 字典 怎么转回来? 传换成字符串后,我用eval执行不就转换回来了吗? str_dic = str([1, 2, 3]) print(str_dic, type(str_dic)) # eval的值: 要不是文件中读出来的,要不是网络上接收来的 res = eval(str_dic) print(res, type(res)) # eval不安全 # eval 要要谨慎的使用,用户的输入/网络上接收的数据/文件中的内容 # eval('import os;os.remove('c:');...') 如移除c盘所有文件 # eval('import urllib;...) 打开病毒网站,下载病毒 # 但是也不是完全不能用 # 你已知的代码 但是可能需要一些拼接 根据你自己的逻辑去做的拼接 # 这时候我们就需要json和pickle模块帮助我们转换
2. json模块 import json dic = {'key': 'value', 'key2': 'value2'} ret = json.dumps(dic) # 序列化:将一个字典转换成一个字符串 print(dic, type(dic)) # {'key': 'value', 'key2': 'value2'} <class 'dict'> # 注意: json转换完的字符串类型的字典中的字符串是由""表示的 print(ret, type(ret)) # {"key": "value", "key2": "value2"} <class 'str'> res = json.loads(ret) # 反序列化:将一个字符串格式的字典转换成一个字典 # 注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示 print(res, type(res)) # 问题1 key是数字也会反序列化成str dic = {1: 'value', 2: 'value2'} ret = json.dumps(dic) # 序列化 print(dic, type(dic)) print(ret, type(ret)) res = json.loads(ret) # 反序列化 print(res, type(res)) # 问题2 value是元组会被序列化成列表 dic = {1: [1, 2, 3], 2: (4, 5, 'aa')} ret = json.dumps(dic) # 序列化 print(dic, type(dic)) print(ret, type(ret)) res = json.loads(ret) # 反序列化 print(res, type(res)) # 问题3 这个数据不是json可序列化的数据类型 s = {1, 2, 'aaa'} json.dumps(s) # 问题4 TypeError: keys must be str json.dumps({(1, 2, 3): 123}) # 为什么会有这么多问题? # json 在所有的语言之间都通用: json序列化的数据 在python上序列化了 那在Java中也可以反序列化 # 能够处理的数据是非常有限的: 字符串 列表 字典 数字 # 字典中的key只能是字符串 # 后端语言 java c c++ c# 数据处理 # 前端语言 在网页上展示 # dumps loads是操作内存的 # 向文件当中记录字典 dic = {'key': 'value', 'key2': 'value2'} ret = json.dumps(dic) # 序列化 with open('json_file','a') as f: f.write(ret) # 从文件中读取字典 with open('json_file','r') as f: str_dic = f.read() dic = json.loads(str_dic) # 在内存中序列化 print(dic.keys()) # dump load 直接操作文件的 dic = {'key': 'value', 'key2': 'value2'} with open('json_file','a') as f: json.dump(dic, f) with open('json_file', 'r') as f: dic = json.load(f) print(dic.keys()) # 问题5 dic = {'key': 'value', 'key2': 'value2'} with open('json_file','a') as f: json.dump(dic, f) # 可以多次dump进去多个数据 json.dump(dic, f) json.dump(dic, f) with open('json_file', 'r') as f: dic = json.load(f) # ,只能load出一个变量,不能多次load出多个变量 print(dic.keys()) # 需求: 就是想要把一个一个的字典放到文件中, 再一个一个取出来??? dic = {'key': 'value', 'key2': 'value2'} with open('json_file', 'a',) as f: str_dic = json.dumps(dic) f.write(str_dic+'\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') str_dic = json.dumps(dic) f.write(str_dic + '\n') with open('json_file', 'r') as f: for line in f: dic = json.loads(line.strip()) print(dic.keys()) # json # dumps loads # 在内存中做数据转换: # dumps 数据类型 转成字符串 序列化 # loads 字符串 转成 数据类型 反序列化 # dump load # 直接将数据类型写入文件,知己从文件中读出数据类型 # dump 数据类型 写入 文件 序列化 # load 文件中 读出 数据类型 反序列化 # json是所有语言都通用的一种序列化格式 # 只支持 列表 字典 字符串 数字 # 字典的key必须是字符串 # 中文序列化后查看的是ascii编码 dic = {'key': '你好'} print(json.dumps(dic, ensure_ascii=False)) # json的格式化输出(了解就行) import json data = {'username':['李华','二愣子'],'sex':'male','age':16} json_dic2 = json.dumps(data, sort_keys=True, indent=2, separators=(',', ':'),ensure_ascii=False) print(json_dic2) # 存文件/传网络
2. pickle模块
import pickle # pickle模块 # 1.支持在python中几乎所有的数据类型 dic = {(1, 2, 3): {'a', 'b'}, 1: 'abc'} # 2.dumps 序列化的结果只能是字节 ret = pickle.dumps(dic) print(ret) print(pickle.loads(ret)) # 3.只能在python中使用 # 4.在和文件操作的时候,需要用rb wb的模式打开文件 # 5.可以多次dump 和 多次load # dump load 操作文件 # dump with open('pickle_file', 'wb') as f: pickle.dump(dic, f) # load with open('pickle_file', 'rb') as f: ret = pickle.load(f) print(ret, type(ret)) # 可以多次dump 和 多次load dic = {(1, 2, 3): {'a', 'b'}, 1: 'abc'} dic1 = {(1, 2, 3): {'a', 'b'}, 2: 'abc'} dic2 = {(1, 2, 3): {'a', 'b'}, 3: 'abc'} dic3 = {(1, 2, 3): {'a', 'b'}, 4: 'abc'} # 多次dump with open('pickle_file', 'wb') as f: pickle.dump(dic, f) pickle.dump(dic1, f) pickle.dump(dic2, f) pickle.dump(dic3, f) # 多次load with open('pickle_file', 'rb') as f: ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) ret = pickle.load(f) print(ret, type(ret)) # 拿次数大于数据量会报错 # 用异常处理 with open('pickle_file', 'rb') as f: while True: try: ret = pickle.load(f) print(ret, type(ret)) except EOFError: break