一、subprocess(用来执行系统命令)

import os

cmd = r'dir D:xxx | findstr "py"'
# res = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
# # 从管道中读取数据 管道就是 两个进程通讯的媒介
# # print(type(res.stdout.read().decode("GBK")))
# print(res.stdout.read().decode("GBK"))
# print(res.stderr.read().decode("GBK"))
subprocess使用当前系统默认编码,得到结果为bytes类型,在windows下需要用gbk解码。

Conclusion

subprocess 主要用于执行系统指令 (启动子进程) 与os.system的不同在于
  subprocess 可以与这个子进程进行数据交换

二、hashlib(加密)

hash是一种算法 是将一个任意长的数据 根据计算 得到一个固定长度特征码
特征: 不同输入 可能会有相同的结果 几率特别小,相同的输入 必然得到相同结果,由于散列(特征)的性质,从原理来看是不可能 反解。

用来 验证 两个输入的数据是否一致

使用场景:

1.密码验证

2.验证数据是否被篡改 比如游戏安装包 有没有被改过,为了防止别人撞库成功 可用提升密码的复杂度 其次可以为密码加盐 (加点内容进去)

import  hashlib

m = hashlib.md5("aaa".encode("utf-8"))
print(len(m.hexdigest())) 32
# 撞库破解的原理 有人事先 把常见的 明文和密文的对应关系 存到了数据库中
# 运气好就能查询到
pwds = {"aaa":"47bce5c74f589f4867dbd57e9ca9f808"} h1 = hashlib.sha512("".encode("utf-8"))
h2 = hashlib.sha3_512("".encode("utf-8")) # print(len(h.hexdigest()))
print(h1.hexdigest())
print(h2.hexdigest()) # 2b70683ef3fa64572aa50775acc84855 # 加盐
m = hashlib.md5("".encode("utf-8"))
#加
m.update("abcdefplkjoujhh".encode("utf-8")) print(m.hexdigest()) import hmac
# 没啥区别 只是在创建的时候必须加盐
h = hmac.new("abcdefjjjj".encode("utf-8")) h.update("".encode("utf-8")) print(h.hexdigest())

三、configparser(用于解析配置文件的模块)

何为配置文件?
包含配置程序信息的文件就称为配置文件
什么样的数据应作为配置信息?
需要改 但是不经常改的信息 例如数据文件的路径 DB_PATH

配置文件中 只有两种内容
一种是section 分区
一种是option 选项 就是一个key=value形式

用的最多的就是get功能 用来从配置文件获取一个配置选项

import configparser
# 创建一个解析器
config = configparser.ConfigParser()
# 读取并解析test.cfg
config.read("test.cfg",encoding="utf-8")
# 获取需要的信息
# 获取所有分区
# print(config.sections())
# 获取所有选项
# print(config.options("user"))
# 获取某个选项的值
# print(config.get("path","DB_PATH"))
# print(type(config.get("user","age")))
#
# # get返回的都是字符串类型 如果需要转换类型 直接使用get+对应的类型(bool int float)
# print(type(config.getint("user","age")))
# print(type(config.get("user","age"))) # 是否由某个选项
config.has_option()
# 是否由某个分区
# config.has_section() # 不太常用的
# 添加
# config.add_section("server")
# config.set("server","url","192.168.1.2")
# 删除
# config.remove_option("user","age")
# 修改
# config.set("server","url","192.168.1.2") # 写回文件中
# with open("test.cfg", "wt", encoding="utf-8") as f:
# config.write(f)

练习:
做一个登录 首先查看配置文件 是否又包含 用户名和密码 如果由直接登录 如果没有就进行输入用户名密码登录
登录成功后 询问是否要保存密码 如果是 写入配置文件

# import configparser
#
# config = configparser.ConfigParser()
# config.read('login.ini', encoding='utf-8')
# username1 = 'wwl'
# password1 = '123'
# if config.has_option('user','username') and config.has_option('user','password'):
# print('welcome logging')
# exit()
# else:
# username = input('>>>请输入用户名:').strip()
# password = input('>>>请输入密码:').strip()
# if username == username1 and password == password1:
# print('welcome logging')
# print('保存密码请输入1,退出请输入2')
# choice = input('请输入:')
# if choice == '1':
# with open('login.ini', 'wt', encoding='utf-8') as f:
# config.add_section("login")
# config.set("login", "Username",username)
# config.set("login", "Password", password)
# print(config.get('login','Username'))
# config.write(f)
# elif choice == '2':
# exit()
# else:
# print('wrong username or password')
login.ini #产生了新的配置文件

[login]
username = wwl
password = 123

四、logging

一、日志级别:

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不设置

二、 默认级别为warning,默认打印到终端

import logging

logging.debug('调试debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('错误error')
logging.critical('严重critical') '''
WARNING:root:警告warn
ERROR:root:错误error
CRITICAL:root:严重critical

三、为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
format:指定handler使用的日志显示格式。
datefmt:指定日期时间格式。
level:设置rootlogger(后边会讲解具体概念)的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略 #格式
%(name)s:Logger的名字,并非用户名,详细查看 %(levelno)s:数字形式的日志级别 %(levelname)s:文本形式的日志级别 %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有 %(filename)s:调用日志输出函数的模块的文件名 %(module)s:调用日志输出函数的模块名 %(funcName)s:调用日志输出函数的函数名 %(lineno)d:调用日志输出函数的语句所在的代码行 %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数 %(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(thread)d:线程ID。可能没有 %(threadName)s:线程名。可能没有 %(process)d:进程ID。可能没有 %(message)s:用户输出的消息 logging.basicConfig()

四、logging模块的Formatter,Handler,Logger,Filter对象

#logger:产生日志的对象

#Filter:过滤日志的对象

#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端

#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
'''
critical=50
error =40
warning =30
info = 20
debug =10
''' import logging #1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出
logger=logging.getLogger(__file__) #2、Filter对象:不常用,略 #3、Handler对象:接收logger传来的日志,然后控制输出
h1=logging.FileHandler('t1.log') #打印到文件
h2=logging.FileHandler('t2.log') #打印到文件
h3=logging.StreamHandler() #打印到终端 #4、Formatter对象:日志格式
formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',) formmater2=logging.Formatter('%(asctime)s : %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p',) formmater3=logging.Formatter('%(name)s %(message)s',) #5、为Handler对象绑定格式
h1.setFormatter(formmater1)
h2.setFormatter(formmater2)
h3.setFormatter(formmater3) #6、将Handler添加给logger并设置日志级别
logger.addHandler(h1)
logger.addHandler(h2)
logger.addHandler(h3)
logger.setLevel(10) #7、测试
logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.error('error')
logger.critical('critical'

五、应用

"""
logging配置
""" import os
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' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 定义日志输出格式 结束 logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目录 logfile_name = 'all2.log' # log文件名 # 如果不存在定义的日志目录就创建一个
if not os.path.isdir(logfile_dir):
os.mkdir(logfile_dir) # log文件的全路径
logfile_path = os.path.join(logfile_dir, logfile_name) # 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)传递
},
},
} def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC) # 导入上面定义的logging配置
logger = logging.getLogger(__name__) # 生成一个log实例
logger.info('It works!') # 记录该文件的运行状态 if __name__ == '__main__':
load_my_logging_cfg() logging配置文件

五、re(正则表达式相关)

什么是正则表达式?

一堆带有特殊意义的符号组成式子

它的作用,处理(匹配 查找 替换 )字符串。
1.在爬虫中大量使用 其实有框架帮你封装了这些复杂的正则
2.在网站和手机app的注册功能中大量使用 例如判断你的邮箱地址是否正确


import re

# =========单个字符匹配=========
print(re.findall("\n","1\n")) # 匹配换行符
print(re.findall("\t","1asasas121 \t")) # 匹配制表符

# ==========范围匹配===========
print(re.findall("\w","1aA_*")) # 匹配数字字母下划线
print(re.findall("\W","1aA_*,")) # 匹配非数字字母下划线
print(re.findall("\s"," \n\r\t\f")) # 匹配任意空白字符
print(re.findall("\S"," \n\r\t\f")) # 匹配任意非空白字符
print(re.findall("\d","123abc1*")) # 匹配任意非空白字符
print(re.findall("\D","123abc1*")) # 匹配任意非空白字符
# print(re.findall("[abc]","AaBbCc")) # 匹配 a b c都行
# print(re.findall("[^abc]","AaBbCc")) # 除了 a b c都行
# print(re.findall("[0-9]","AaBbCc12349")) # 除了 a b c都行
print(re.findall("[a-z]","AaBbCc12349")) # a-z 英文字母
print(re.findall("[A-z]","AaBbC:c

最新文章

  1. JS 中的事件绑定、事件监听、事件委托
  2. Android Studio编译输出apk文件修改文件名
  3. IPv6协议
  4. css3高级运动keyframes
  5. Beta版本的贡献率
  6. 【HDOJ】1720 A+B coming
  7. 嵌入式ARM-Linux开发工具下载地址合集
  8. ASPxGridView-为每行添加序号
  9. P1050
  10. 华为笔试题--LISP括号匹配 解析及源码实现
  11. ios应用版本号设置规则
  12. linux下jvm优化、tomcat调优
  13. java启动jar包中的指定类
  14. beego快速入门
  15. NOIP Mayan游戏 - 搜索
  16. 【深度学习】Pytorch学习基础
  17. 机器装多个版本php,并安装redis插件报错【已解决】
  18. wamp环境解决局域网不能访问的问题!
  19. nginx docker 方式启动后日志切分的正确姿势
  20. HDU4474_Yet Another Multiple Problem

热门文章

  1. appium随笔
  2. flask 对URL进行安全验证
  3. [转载]WebService服务的三种途径Endpoint Disco WSDL 有什么不同
  4. <转>jmeter(十一)JDBC Request之Query Type
  5. vue editorConfig
  6. 【react懒加载组件】--react-lazyload
  7. asyncio 学习
  8. selenium:2.selenium 键盘事件模拟
  9. django 正向,反向
  10. Golang指针基本介绍及使用案例