第十五章:内置模块(os、sys、json、pickle)

os 模块(重要)

os 模块是与代码所在的操作系统交互的一个接口

文件操作

命令 输出 描述
os.makedirs(r'E:\tools\test\down') 可生成多层递归目录
os.removedirs(r'E:\tools\test\down') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir(r'E:\tools\test\down\ysg') 生成单级目录;相当于 shell 中 mkdir dirname
os.rmdir(r'E:\tools\test\down\ysg') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
s = os.listdir(r'E:\tools') ['123.xls', 'download', 'download.zip' ... ] 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove(r'E:\tools\H03668.day') 删除一个文件
os.rename(r'E:\tools\H03668.day',r'E:\tools\03668.day') 重命名文件/目录
s1 = os.stat(r'E:\tools\H03668.day') os.stat_result(st_mode=33206, ...) 获取文件/目录信息
os.walk(r'E:\tools') ('E:\tools\download', ['zt'], []) 文件遍历
os.stat() 返回属性说明

st_mode: inode 保护模式
st_ino: inode 节点号
st_dev: inode 驻留的设备
st_nlink: inode 的链接数
st_uid: 所有者的用户 ID
st_gid: 所有者的组ID
st_size: 普通文件以字节为单位的大小;包含等待某些特殊文件的数据
st_atime: 上次访问的时间
st_mtime: 最后一次修改的时间
st_ctime: 由操作系统报告的"ctime",在某些系统上(如Unix)是最新的元数据更改的时间,在其它系统上(如 Windows)是创建时间(详细信息参见平台的文档)

类命令操作

命令 输出 描述
os.system("ipconfig") 运行命令行命令,并显示结果,与 pycharm 的编码格式有关
os.popen('ipconfig').read() 运行命令行命令,并显示结果,与 pycharm 的编码格式无关
os.getcwd() E:\tools 获取当前工作目录,即当前 python 脚本工作的目录路径,相当于 shell 中的 pwd
os.chdir('..') 改变当前脚本工作目录;相当于 shell 下 cd

os.path

数据参数

path = r'E:\tools\H03668.day'
path1 = r'F:\config.ini'
path2 = r'E:\tools'
path3 = r'mysql'
命令 输出 描述
p = os.path.abspath('.') Y:\py\use 返回 path 规范化的绝对路径
p1 = os.path.split(path) ('Y://py//use//czx//one', 'qw') 将 path 分割成目录和文件名二元组返回
p2 = os.path.dirname(path) Y://py//use//czx//one 返回 path 的目录
p3 = os.path.basename(path) qw 返回 path 最后的文件名(可返回空)
p4 = os.path.exists(path) True path 存在,返回 True(或 False)
p5 = os.path.isabs('.') False 如果 path 是绝对路径,返回 True
p6 = os.path.isfile(path) False path 是存在的文件,返回 True(或 False)
p7 = os.path.isdir(path) True path 是存在的目录,返回 True(或 False)
p8 = os.path.getsize(path1) 6656 返回 path 的大小
p9 = os.path.getatime(path) 1665369606.441087 返回 path 所指向的文件或者目录的 最后访问时间
p10 = os.path.getctime(path) 1666171187.7370238 返回 path 所指向的文件或者目录的 创建时间
p11 = os.path.getmtime(path) 1665369589.5532897 返回 path 所指向的文件或者目录的 最后修改时间
p12 = os.path.join(path2,path3) E:\tools\mysql 路径拼接,第一个绝对路径之前的参数将被忽略

os 模块属性

命令 输出 描述
os.sep win下为 "\\" Linux下为 "/" 输出操作系统特定的路径分隔符
os.linesep win下为 "\r\n" Linux下为 "\n" 输出当前平台使用的行终止符
os.pathsep win下为 “;” Linux下为 ":" 输出用于分割文件路径的字符串
os.name win -> 'nt' Linux -> 'posix' 输出字符串指示当前使用平台

sys 模块

sys 模块是与 python 解释器交互的一个接口

sys.argv           返回 List,第一个元素是程序本身路径
sys.exit(n)        退出程序,正常退出时 exit(0),错误退出 sys.exit(1)
sys.version        获取 Python 解释程序的版本信息
sys.path           返回模块的搜索路径,初始化时使用 PYTHONPATH 环境变量的值
sys.platform       返回操作系统平台名称
sys.getrecursionlimit()		获取 python 解释器默认最大递归深度
	sys.setrecursionlimit(2000)  # 修改 python 解释器默认最大递归深度

sys.argv 的例子:

# 命令行执行>>> python test.py ysg 123

# test.py 文件内容
import sys

res = sys.argv
if len(res) != 3:
    print('执行命令缺少了用户名或密码')
else:
    username = res[1]
    password = res[2]
    if username == 'ysg' and password == '123':
        print('{} 您好,文件正常执行'.format(username))
    else:
        print('您不是 {} 无权执行该文件'.format(username))

json 模块(重要)

dumps(序列化方法)、loads(反序列化方法),这两个直接对 内存中的数据进行操作
json 本身是单引号的,内部原本是字符串元素要用双引号

dumps() 与 loads()

dumps()

dumps 参数

参数 描述
sort_keys=True 排序
indent 整齐打印,填充物为空格
separators=() 紧凑编码
ensure_ascii=False 输出为中文,(中文显示默认为 ascii 码)

例子:

import json

data = {'username': ['张三', '李四'], 'sex': 'male', 'age': 16}
json_dic2 = json.dumps(data, sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False)
print(json_dic2)

# {
#     "age":16,
#     "sex":"male",
#     "username":[
#         "张三",
#         "李四"
#     ]
# }

字典与序列化的比较

import json

dic = {"k": 'v'}
print(type(dic), dic)  # 输出结果:<class 'dict'> {'k': 'v'}

str_d = json.dumps(dic)  # 序列化
print(type(str_d), str_d)  # 输出结果:<class 'str'> {"k": "v"}

loads()

import json

dic = {"k": 'v'}
str_d = json.dumps(dic)  # 序列化 输出结果:<class 'str'> {"k": "v"}
dic_d = json.loads(str_d)  # 反序列化
print(type(dic_d), dic_d)  # 输出结果:<class 'dict'> {'k': 'v'}

元组也可以序列化(但被当做列表处理了)

import json

dic = (1, 2, 3)
print(type(dic), dic)   # <class 'tuple'> (1, 2, 3)

str_d = json.dumps(dic)
print(type(str_d), str_d)   # <class 'str'> [1, 2, 3]

dic_d = json.loads(str_d)
print(type(dic_d), dic_d)   # <class 'list'> [1, 2, 3]

dump() 与 load()

dump(序列化方法)、load(反序列化方法),这两个是 对文件相关的操作
dump load 一次性写入 一次性读出

import json

dic = {1: "a", 2: "b"}

with open('E:/tools/file.txt', 'w', encoding='utf-8') as fw:
    ret = json.dump(dic, fw)
print(type(ret), ret)  # <class 'NoneType'> None


with open('E:/tools/file.txt', encoding='utf-8') as fr:
    res = json.load(fr)
print(type(res), res)  # <class 'dict'> {'2': 'b', '1': 'a'}

json 模块实战

# 使用 json 文件,实现用户 登录与注册 功能

def sign_in(db_dir):
    username = input('username>>>:').strip()
    target_user_file_path = os.path.join(db_dir, '{}.json'.format(username))
    if not os.path.isfile(target_user_file_path):
        print('用户名不正确')
    else:
        password = input('password>>>:').strip()
        # 2.获取用户真实数据字典
        with open(target_user_file_path, 'r', encoding='utf-8') as f:
            real_user_dict = json.load(f)
        if password == real_user_dict.get('password'):
            print('登录成功')
        else:
            print('密码错误')

def register(db_dir):
    username = input('username>>>:').strip()
    password = input('password>>>:').strip()
    dic = {'username': username, 'password': password}
    with open(os.path.join(db_dir, '{}.json'.format(username)), 'w', encoding='utf-8') as fw:
        json.dump(dic, fw)
    pass

def run():
    db_dir = os.path.join(os.getcwd(), 'db')
    print(db_dir)
    if not os.path.exists(db_dir):
        os.mkdir(db_dir)
    while 1:
        info = '''
        1.登录
        2.注册
        '''
        print(info)
        num = input('>>>').strip()
        if num == '1':
            sign_in(db_dir)
        elif num == '2':
            register(db_dir)
        else:
            print('已退出')
            return

if __name__ == '__main__':
    run()

pickle 模块(非常不常用)

用法与 json 模块一致,但是只用于 python,无法兼容其它语言,且只能与要存储的 python 对象在同一文件中使用。

它能够实现任意对象与文本之间的相互转化,也可以实现任意对象与二进制之间的相互转化。也就是说,pickle 可以实现 Python 对象的存储及恢复。

pickle 模块提供了以下 4 个函数供我们使用:

  • dumps():将 Python 中的对象序列化成二进制对象,并返回对象
  • loads():读取给定的二进制对象数据,并将其转换为 Python 对象
  • dump():将 Python 中的对象序列化成二进制对象,并写入文件
  • load():读取指定的序列化数据文件,并返回对象
# dumps() 和 loads() 是基于内存的 python 对象与二进制互转
# dump() 和 load() 是基于文件的 python 对象与二进制互转

存储 list 对象

import pickle


list = [1, 2, 3, 12, 41]

with open('pickle_lit1', 'wb') as fw:
    pickle.dump(list, fw)

with open('pickle_lit1', 'rb') as fr:
    ret = pickle.load(fr)
    print(ret)

存储 class 对象

class Test:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func1(self):
        print('this is func1')


t = Test('ysg', '25')


# 存储 Test 类
with open('pickle_class', 'wb') as fw:
    pickle.dump(Test, fw)

with open('pickle_class', 'rb') as fr:
    ret = pickle.load(fr)
    r = ret('ysg', 25)
    print(ret)  # <class '__main__.Test'>
    print(r.name)   # ysg
    print(r.age)    # 25
    r.func1()    # this is func1
    
    
# 存储实例化后的 t 对象
with open('pickle_class', 'wb') as fw:
    pickle.dump(t, fw)

with open('pickle_class', 'rb') as fr:
    ret = pickle.load(fr)
    print(ret)  # <__main__.Test object at 0x015B3F88>
    print(ret.name)   # ysg
    print(ret.age)    # 25
    ret.func1()    # this is func1

作业

1.编写一个统计指定文件类型的脚本工具
 输入指定类型的文件后缀
     eg:.txt
 并给出一个具体路径 之后统计该类型文件在该文件下的个数
  ps:简单实现即可 无需优化
2.针对json实操 尝试单文件多用户(一行一个)是否可实现>>>:哪个更方便
    不要求完成 单纯体会两种思路的难易
3.编程小练习
 有一个目录文件下面有一堆文本文件
     eg:
      db目录
            J老师视频合集
            R老师视频合集
            C老师视频合集
            B老师视频合集
 文件内容自定义即可 要求循环打印出 db 目录下所有的文件名称让用户选择
  用户选择哪个文件就自动打开该文件并展示内容
  涉及到文件路径全部使用代码自动生成 不准直接拷贝当前计算机固定路径
4.周末大作业(尝试编写)
 # 项目功能
    1.用户注册
     2.用户登录
     3.添加购物车
     4.结算购物车
 # 项目说明
    用户数据采用json格式存储到文件目录db下 一个用户一个单独的文件
     数据格式 {"name":"jason","pwd":123} 
         # ps:文件名可以直接用用户名便于校验
     用户注册时给每个用户添加两个默认的键值对(账户余额 购物车)
      {"balance":15000,"shop_car":{}}
     添加购物车功能 商品列表可以自定义或者采用下列格式
            good_list = [
                    ['挂壁面',3]
                    ['印度飞饼', 22]
                 ['极品木瓜', 666], 
                 ['土耳其土豆', 999],  
                 ['伊拉克拌面', 1000],  
                 ['董卓戏张飞公仔', 2000],  
                 ['仿真玩偶', 10000] 
            ]
      用户可以反复添加商品,在购物车中记录数量
        {'极品木瓜':[个数,单价]}
     结算购物车
      获取用户购物车中所有的商品计算总价并结算即可
  针对添加购物车和结算只有登录的用户才可以执行

解答

# 1.编写一个统计指定文件类型的脚本工具
import os

def count_file(path, suffix):
    file_lit = os.listdir(path)
    suf_lit = []
    for i in file_lit:
        if i.split('.')[-1] == suffix:
            suf_lit.append(i)
    print(len(suf_lit))


if __name__ == '__main__':
    path = input('输入路径>>>').strip()
    suffix = input('输入文件后缀>>>').strip()
    count_file(path, suffix)
    
    
# 3.编程小练习
import os


def vim_file(path):
    with open(path, 'r', encoding='utf-8') as fr:
        print('打开文件:{}'.format(path))
        total = fr.readlines()
        for i in total:
            print(i)
        print()


def run():
    db_path = os.getcwd()
    lit = ['J老师视频合集.txt', 'R老师视频合集.txt', 'C老师视频合集.txt', 'B老师视频合集.txt']
    while 1:
        for num, i in enumerate(lit):
            print('{}.{}'.format(num, i))
        n = input('输入要查看文件的编号(q)>>>').strip()
        path = os.path.join(db_path, 'db', lit[int(n)])
        vim_file(path)
        if n == 'q':
            print('已退出')
            return


if __name__ == '__main__':
    run()
posted @ 2022-10-20 21:28  亦双弓  阅读(233)  评论(0)    收藏  举报