常用模块——sys、os、logging、hashlib、JSON、pickle

os模块

​ os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口,大多时候用于文件处理。下面对os模块的一些常用方法做出介绍。

最常用:

方法说明
os.makedirs(‘dirname1/dirname2’)可生成多层递归目录
os.removedirs(‘dirname1’)若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir(‘dirname’)生成单级目录;相当于shell中mkdir dirname
os.rmdir(‘dirname’)删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir(‘dirname’)列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove()删除一个文件
os.rename(“oldname”,“newname”)重命名文件/目录
os.system(“bash command”)运行shell命令,直接显示
os.getcwd()获取当前工作目录,即当前python脚本工作的目录路径
os.chdir(“dirname”)改变当前脚本工作目录;相当于shell下cd
os.path.abspath(path)返回path规范化的绝对路径
os.path.split(path)将path分割成目录和文件名二元组返回
os.path.dirname(path)返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path)返回path最后的文件名。如果path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path)如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path)如果path是绝对路径,返回True
os.path.isfile(path)如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path)如果path是一个存在的目录,则返回True。否则返回False
os.path.getsize(path)返回path的大小
os.environ获取系统环境变量

了解:

方法说明
os.stat(‘path/filename’)获取文件/目录信息
os.popen(“bash command”).read()运行shell命令,获取执行结果
os.curdir返回当前目录: (‘.’)
os.pardir获取当前目录的父目录字符串名:(‘…’)
os.sep输出操作系统特定的路径分隔符,win下为\,Linux下为”/“
os.linesep输出当前平台使用的行终止符,win下为”\r\n”,Linux下为”\n”
os.pathsep输出用于分割文件路径的字符串 ,win下为;,Linux下为:
os.name输出字符串指示当前使用平台。win->’nt’; Linux->’posix’
os.path.join(path1[, path2[, …]])将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path)返回path所指向的文件或者目录的最后访问时间
os.path.getmtime(path)返回path所指向的文件或者目录的最后修改时间

**注意:**os.stat(‘path/filename’) 说明

# 返回结果例如:
os.stat_result(st_mode=16895, st_ino=2251799814457778, st_dev=1656970066, st_nlink=1, st_uid=0, st_gid=0, st_size=8192, st_atime=1644059800, st_mtime=1644059799, st_ctime=1634989723)

# 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)是创建时间(详细信息参见平台的文档)。

sys模块

​ sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。下面对sys模块的一些常用方法做出介绍。

方法说明
sys.argv命令行参数List,第一个元素是程序本身路径
sys.modules.keys()返回所有已经导入的模块列表
sys.exc_info()获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息
sys.exit(n)退出程序,正常退出时exit(0)
sys.hexversion获取Python解释程序的版本值,16进制格式如:0x020403F0
sys.version获取Python解释程序的版本信息
sys.maxint最大的Int值
sys.maxunicode最大的Unicode值
sys.modules返回系统导入的模块字段,key是模块名,value是模块
sys.path返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform返回操作系统平台名称
sys.stdout标准输出
sys.stdin标准输入
sys.stderr错误输出
sys.exc_clear()用来清除当前线程所出现的当前的或最近的错误信息
sys.exec_prefix返回平台独立的python文件安装的位置
sys.byteorder本地字节规则的指示器,big-endian平台的值是’big’,little-endian平台的值是’little’
sys.copyright记录python版权相关的东西
sys.api_version解释器的C的API版本

注意:sys.argv用法说明

"""
在我们使用命令行运行python程序的时候,我们可以通过如下方式来运行:
	python3 test.py
但是同时我们也可以在后面继续传一些参数,在一些特定的情况下可以提高我们的效率,参数之间通过空格来隔开,比如:
	python3 test.py 111 222 333
而sys.argv就是存储这些参数的列表,列表中第一个元素是程序本身的路径,我们可以通过列表的取值方式来取其中的数据
"""


import sys

# print(sys.argv)
# print(sys.argv[1])
# print(sys.argv[2])
# print(sys.argv[3])

json&pickle模块

序列化

​ 把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening。通俗来说,就是将字典、列表等数据类型转换成一个字符串的过程叫作序列化。

​ 序列化的目的是以某种存储形式使自定义对象持久化;而且将对象从一个地方传递到另一个地方;并且使程序更具维护性。因此序列化最大的优点就是进行跨平台数据交互。

json模块

​ json序列化并不是python独有的,json序列化在java等语言中也会涉及到,因此使用json序列化能够达到跨平台传输数据的目的。在python中我们使用json模块来实现json序列化和反序列化。

序列化与反序列化过程图示:

image-20220206142810942

json数据类型与python数据类型对照表:

Json类型Python类型
object {}dict
array []list
string “string”str unicode
520.13int或float
true/falseTrue/False
nullNone

json模块中序列化方法:json.dumps(),json.dump()

json模块中反序列化方法:json.loads(),json.load()

代码示例:

import json

user_dict = {"username": "mary"} # {'username': 'mary'}
print(user_dict, type(user_dict)) # dict  {'username': 'mary'}
print(user_dict)
# 序列化字典
json_str=json.dumps(user_dict) 
print(json_str, type(json_str))  # {"username": "mary"}  # json格式的数据最大特征就是双引号

# 反序列化
res = json.loads(json_str)
print(res, type(res))



# 小案例:将一个字典写入到文件中,并且读出来的时候还必须是字典
'''
    json.dumps   json.loads 实现,我们发现在读出文件内容的时候数据类型不是字典,而是字符串,没有达到我们的要求。
'''

user_dict = {"username": "mary"}

with open('a.txt', 'w', encoding='utf-8') as f:
    data = json.dumps(user_dict)
    f.write(data)

with open('a.txt', 'r', encoding='utf-8') as f:
    print(f.read(), type(f.read()))

    
'''
    json.dump   json.load实现,我们可以看到完全符合我们的要求。
'''
    
with open('b.txt', 'w', encoding='utf-8') as f:
    json.dump(user_dict, f)  
    # 内部完成了两件事: 1.序列化成字符串 	2.写入文件

with open('b.txt', 'r', encoding='utf-8') as f:
    data=json.load(f)  
    # 内部完成了两件事: 1. 先读文件	 2. 反序列化
    print(data, type(data))

在我们使用json进行序列化的时候,如果有中文字符,会出现我们所谓的乱码问题,这是为什么呢?

# 查看源码,我们发现在dumps方法的参数中有一个参数ensure_ascii默认为True,这使得我们的字符串进行了编码,我们可以通过修改参数的默认值来解决这个问题
"""
def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
        allow_nan=True, cls=None, indent=None, separators=None,
        default=None, sort_keys=False, **kw):
"""

user_dict = {'aaa': 'hello 世界'}
print(json.dumps(user_dict, ensure_ascii=False))
pickle模块

​ Pickle序列化和所有其他编程语言特有的序列化问题一样,它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,即不能成功地反序列化也没关系。但是pickle的优点是可以存储Python中的所有的数据类型,包括对象,而json不可以存储对象。

​ 注意:pickle能够序列化所有的数据类型,并且序列化之后的结果都是二进制格式,如果需要使用文件存储,则要注意文件的模式为b模式。

代码示例:

import pickle

user_dict = {"username": "mary"}

res = pickle.dumps(user_dict)
# print(pickle.dumps(user_dict))
print(pickle.loads(res))


with open('a.txt', 'wb') as f:
    pickle.dump(user_dict, f)
    
with open('a.txt', 'rb') as f:
    pickel_data = pickle.load(f)
print(pickle_data)

hashlib模块

​ hash是一种算法(Python3.版本里使用hashlib模块代替了md5模块和sha模块,主要提供 SHA1、SHA224、SHA256、SHA384、SHA512、MD5 算法),该算法接受传入的内容,经过运算得到一串hash值。

​ hash值的特点:

  1. 只要传入的内容一样,得到的hash值一样,可用于非明文密码传输时密码校验
  2. 不能由hash值返解成内容,即可以保证非明文密码的安全性
  3. 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的,可以用于对文本的哈希处理

​ Python的hashlib模块即提供了常见的摘要算法。

代码示例:

import hashlib

md5 = hashlib.md5()  # 代表使用md5算法
md5.update('helloworld'.encode('utf-8')) # 需要加密的数据
# 加密之后的结果
res=md5.hexdigest()
print(res)  # fc5e038d38a57032085441e7fe7010b0


# md5 = hashlib.md5()  # 代表使用md5算法
# md5.update('h'.encode('utf-8')) # 需要加密的数据
# md5.update('e'.encode('utf-8')) # 需要加密的数据
# md5.update('l'.encode('utf-8')) # 需要加密的数据
# md5.update('l'.encode('utf-8')) # 需要加密的数据
# md5.update('o'.encode('utf-8')) # 需要加密的数据
# md5.update('world'.encode('utf-8'))
# # 加密之后的结果
# res=md5.hexdigest()
# print(res) # fc5e038d38a57032085441e7fe7010b0


'''
注意:
	1. 被加密的数据必须是二进制
    2. 被加密的数据可以分多次传递
'''

​ hash值的特点是只要传入的内容一样,结果就会一样,因此会出现使用人们常用的密码来得到hash值撞库破解密码,这样我们的安全性就有所缺失,为了解决这样的问题,我们可以通过加盐处理,来进一步保证数据的安全性。

撞库破解密码:

import hashlib

# 假定我们知道常用的密码会设置如下几个
pwd_list = [
    '1234567',
    'qwerty',
    '123qwe',
    '147258369',
    '987654321',
]


def make_pwd_dic(pwd_list):
    dic = {}
    for pwd in pwd_list:
        m = hashlib.md5()
        m.update(pwd.encode('utf-8'))
        dic[pwd] = m.hexdigest()
    return dic


def break_code(hash_pwd, pwd_dic):
    for k, v in pwd_dic.items():
        if v == hash_pwd:
            print('密码是===>%s' % k)


hash_pwd = 'd8578edf8458ce06fbc5bb76a58c5ca4'
break_code(hash_pwd, make_pwd_dic(pwd_list))

加盐处理:

import hashlib


md5 = hashlib.md5()
# 定义一个盐(随机的一个字符串)
salt = '!@#¥%'
s = salt+'123456'
md5.update(s.encode('utf-8'))
res=md5.hexdigest()
print(res)
'''注意:密文不能反解出明文'''

logging日志模块

# 日志等级
import logging  
logging.debug('debug message')  10
logging.info('info message')  	20
logging.warning('warning message')  30
logging.error('error message')  40
logging.critical('critical message') 50
配置日志字典
# 在需要的时候进行copy即可
import logging
import logging.config

standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

logfile_path = 'a3.log'
# log配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
    },
    'filters': {},  # 过滤日志
    'handlers': {
        #打印到终端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
            'formatter': 'standard',
            'filename': logfile_path,  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置  空字符串作为键 能够兼容所有的日志
        '': {
            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
            'level': 'DEBUG',
            'propagate': True,  # 向上(更高level的logger)传递
        },  # 当键不存在的情况下 (key设为空字符串)默认都会使用该k:v配置
    },
}


# 使用配置字典
logging.config.dictConfig(LOGGING_DIC)  # 自动加载字典中的配置
logger1 = logging.getLogger('xxx')
logger1.debug('好好的 不要浮躁 努力就有收获')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值