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序列化和反序列化。
序列化与反序列化过程图示:
json数据类型与python数据类型对照表:
Json类型 | Python类型 |
---|---|
object {} | dict |
array [] | list |
string “string” | str unicode |
520.13 | int或float |
true/false | True/False |
null | None |
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值的特点:
- 只要传入的内容一样,得到的hash值一样,可用于非明文密码传输时密码校验
- 不能由hash值返解成内容,即可以保证非明文密码的安全性
- 只要使用的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('好好的 不要浮躁 努力就有收获')