dya19

1. os.path的方法

impot os

# os.path.abspath 返回path规范化的绝对路径
# (1)把路径中不符合规范的/改成改成操作系统默认的格式
    path = os.path.abspath('D:/pythonproject/day19/03 os.path方法.py')
    print(path)  # D:pythonprojectday193 os.path方法.py
# (2)能够给能找到的相对路径改成绝对路径
    path = os.path.abspath('03 os.path方法.py')
    print(path)  # D:pythonprojectday193 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:pythonprojectday193 os.path方法.py')
    print(res)

# 判断是否是绝对路径 Ture/False
    res1 = os.path.isabs('03 os.path方法.py')
    res2 = os.path.isabs(r'D:pythonprojectday193 os.path方法.py')
    print(res1)  # False
    print(res2)  # True

# 判断是否是文件
    print(os.path.isfile(r'D:pythonprojectday193 os.path方法.py'))
# 判断是否是文件夹
    print(os.path.isdir(r'D:pythonprojectday193 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:pythonprojectday193 os.path方法.py')
    print(size)  # 5071

    ret1 = os.path.getsize('D:pythonprojectday19')
    ret2 = os.path.getsize('D:pythonprojectday18')
    ret3 = os.path.getsize('D:pythonprojectday17')
    print(ret1, ret2, ret3)  # 4096 4096 4096
# windows所有的文件夹 都至少是4096个字节
# 还有可能是 8192
# mac上 64字节 + 32字节/新文件
#练习题
# 使用python代码统计一个文件夹中的所有文件的总大小
# 你需要统计文件夹大小
# D:pythonprojectday17 文件夹的大小
    # 拿到这个文件夹下所有的文件夹 和 文件
    # 是文件就取大小
    # 是文件夹 再打开这个文件夹: 文件/文件夹

# 递归
    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:pythonprojectday01','D:pythonprojectday02',...]
        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:pythonprojectday01')  lst=['D:pythonprojectday01']
            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+'
')
        str_dic = json.dumps(dic)
        f.write(str_dic + '
')
        str_dic = json.dumps(dic)
        f.write(str_dic + '
')

    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
原文地址:https://www.cnblogs.com/kangqi452/p/11457275.html