'''
logging 模块
为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参数会被忽略。即:不可同时输出终端和写入文件
format参数中可能用到的格式化串:
%(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用户输出的消息
'''
# import logging
#
# # 指定日志写入格式和级别,不可同时操作 终端打印和文件写入 操作
# logging.basicConfig(filename='access.log',
# format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
# datefmt='%Y-%m-%d %H:%M:%S %p',
# level=10)
#
# # 用来产生不同类型的日志,严重级别从小到大
# logging.debug('debug日志') #10
# logging.info('info日志') #20
# logging.warning('warning日志') #30
# logging.error('error日志') #40
# logging.critical('critical日志') #50
'''
logging模块中的 Formatter,Handler,Logger,Filter 对象
logger 对象:负责产生各种级别的日志
filter 对象:负责过滤日志的对象
Handler 对象:接收日志然后控制打印到不同的地方
FileHandler用来打印到文件中,StreamHandler用来打印到终端
Formatter 对象:可以定制不同的日志格式对象
然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
'''
# import logging
#
# # logger对象产生日志
# logger = logging.getLogger('用户交易') # 日志名用来标识日志绑定的相关用户
#
# # filter对象过滤日志
#
# # handler对象控制日志输出位置
# fh1 = logging.FileHandler('a1.log',encoding='utf-8') # 打印到文件
# fh2 = logging.FileHandler('a2.log',encoding='utf-8') # 打印到文件
# ch = logging.StreamHandler() # 打印到终端
#
# # formatter对象定制handler日志格式
# 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',)
#
# # 绑定logger对象和handler对象
# logger.addHandler(fh1)
# logger.addHandler(fh2)
# logger.addHandler(ch)
#
# # 绑定handler对象和formatter对象
# fh1.setFormatter(formmater1)
# fh2.setFormatter(formmater2)
# ch.setFormatter(formmater3)
#
# # 设置日志级别。有logger对象和handler对象两层关卡,必须都满足级别及以上级别,最终日志才会放行,通常二者级别相同
# logger.setLevel(10)
#
# fh1.setLevel(10)
# fh2.setLevel(10)
# ch.setLevel(10)
#
# # 使用logger对象产生日志
# logger.debug('debug')
# logger.info('info')
# logger.warning('warning')
# logger.error('error')
# logger.critical('critical')
# *--------------------------------------
# logging模块的使用模板
# log配置字典
# 定义三种日志输出格式 开始
# 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文件名
#
# logfile_path = os.path.join(logfile_dir, logfile_name)
#
#
# 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': {
# '': { #空key用来保证任意名字取到的值都是默认格式
# 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
# 'level': 'DEBUG',
# },
# },
# }
# 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()
# ----------------------------------------
'''
shelve 模块 :一种pthon自带的序列化工具,可自动序列化
可以直接通过import shelve来引用。
shelve类似于一个存储持久化对象的持久化字典,即字典文件。
使用方法也类似于字典。
使用方法:
1.open
2.读写
3.close
注意: shelve 模块只有一个open函数,返回类似字典的对象,可读可写;
key必须为字符串,而值可以是python所支持的数据类型
'''
# import shelve
#
# # 保存对象至shelve文件中(序列化):
# db = shelve.open('shelveDict') # 打开一个文件
# db['wangzhe'] = 'wangzhe' # 向文件中添加内容,添加方式与给字典添加键值对相同
# db['lijianguo'] = 'lijianguo'
# db.close() #关闭文件
#
# # 从文件中读取对象(反序列化):
# import shelve
# db = shelve.open('shelveDict') #打开文件
# a = db.get('wangzhe')
# print(db['wangzhe']) #向从字典中获取键的方式一样读取内容
# print(db['lijianguo']) #结果为{'age': 25, 'name': 'lijianguo'}
# db.close() #关闭文件
#
# # 更新文件中的数据:
# import shelve
# db = shelve.open('shelveDict') #打开文件
# wangzhe = db['wangzhe'] #从文件中读取之前存储的对象
# wangzhe['name'] = 'wang zhe' #直接对对象进行修改
# db['wangzhe'] = wangzhe #重新存储至字典文件对象中
# print(db['wangzhe'] ) #结果如下{'age': 24, 'name': 'wang zhe'}
# db.close() #关闭文件
'''
xml模块:
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单。
语法:
一、任何的起始标签都必须有一个结束标签。
二、可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。
这种语法是在大于符号之前紧跟一个斜线(/),例如<百度百科词条/>。
XML解析器会将其翻译成<百度百科词条></百度百科词条>。
三、标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,
例如<tag1>
<tag2>
</tag2>
</tag1>
这好比是将起始和结束标签看作是数学中的左右括号:
在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
四、所有的特性都必须有值。即:特性指的是属性
五、所有的特性都必须在值的周围加上双引号。
使用场景:
1.配置文件
2.常规的数据交换
与json的区别:
xml的优点:
(1)格式统一
(2)容易与其他系统进行远程交互,数据共享比较方便
xml的缺点:
(1)xml文件庞大,文件格式复杂,传输占带宽
(2)服务器和客户端都需要花费大量代码来解析xml,导致服务器和客户端代码变得异常复杂且不易维护
(3)客户端和服务端解析xml花费较多的资源和时间
json的优点:
(1)数据格式比较简单,易于读写,格式是压缩的,占用带宽小
(2)易于解析,包括JavaScript可以通过简单的通过eval_r()进行json数据的读取
json的缺点:
(1)没有xml那么通用
(2)json格式目前还在推广阶段
ElmentTree 表示文件的节点树
Elment 表示一个节点:
属性:
1.text : <>text</>
2.attrib : 所有属性
3.tag: 标签的名字
方法:
get 获取某个属性的值
'''
# import xml.etree.ElementTree as et
# 获取节点树
# tree = et.parse('TEST.xml') #读取xml到内存,的到一个包含所有数据的节点树
# print(tree)
# 查找标签
# root = tree.getroot()# 获取根标签
# print(root.iter('year')) #全文搜索,返回迭代器对象
# print(root.find('country')) #在root的子节点找,只找一个,且只找第一个
# print(root.findall('country')) #在root的子节点找,找所有
# 遍历xml文件
# for country in root:
# print(country.tag,country.attrib,country.text)
# for t in country:
# print(t.tag,t.attrib,t.text)
#获取一个属性
# print(root.find('country').get('name'))
#
# 修改xml文件
# 读取到内存 并在内存中修改
# tree = et.parse('TEST.xml')
# for country in tree.findall('country'):
# yeartag = country.find('year')
# yeartag.text = str(int(yeartag.text) + 1)
# # 写回文件
# tree.write('TEST.xml',encoding='utf-8',xml_declaration=False)
#
# for node in root.iter('year'):
# new_year = int(node.text) + 1
# node.text = str(new_year)
# node.set('updated', 'yes')
# node.set('version', '1.0')
# tree.write('test.xml')
# 删除
# tree = et.parse('TEST.xml')
# root = tree.getroot()
# for country in root.findall('country'):
# rank = int(country.find('rank').text)
# if rank > 50:
# root.remove(country)
# tree.write('output.xml')
# 增加xml文件
#在country内添加(append)节点year2
# import xml.etree.ElementTree as ET
# tree = ET.parse("a.xml")
# root=tree.getroot()
# for country in root.findall('country'):
# for year in country.findall('year'):
# if int(year.text) > 2000:
# year2=ET.Element('year2')
# year2.text='新年'
# year2.attrib={'update':'yes'}
# country.append(year2) #往country节点下添加子节点
# tree.write('a.xml.swap')
# 创建xml文档
# 方法一:
# import xml.etree.ElementTree as ET
# # 创建根标签
# new_xml = ET.Element("namelist")
# #简单创建xml
# # name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"})
# # age = ET.SubElement(name, "age", attrib={"checked": "no"})
# # sex = ET.SubElement(name, "sex")
# # sex.text = '33'
# # name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"})
# # age = ET.SubElement(name2, "age")
# # age.text = '19'
# # # 写入文件
# et = ET.ElementTree(new_xml) #生成文档对象
# et.write("test1.xml", encoding="utf-8", xml_declaration=True)
# ET.dump(new_xml) # 打印生成的格式
# 方法二:
# import xml.etree.ElementTree as ET
# new_xml = ET.Element("namelist")
# # 创建节点树 et
# et = ET.ElementTree(new_xml) # 生成文档对象
# person = ET.Element('person')
# person.attrib['name'] = 'test'
# person.attrib['sex'] = 'male'
# person.attrib['age'] = '18'
# person.attrib['text'] = '这是一个person标签'
# new_xml.append(person)
# # # 写入文件
# et.write("test1.xml", encoding="utf-8", xml_declaration=True)
# ET.dump(new_xml) # 打印生成的格式
'''
configparser 模块 :配置文件解析模块,解析配置文件(.ini .cfg)
配置文件格式:
1.section 分区
2.option 选项
注:一个文件可以有多个section,一个section可以有多个选项
例如:
# 注释1
; 注释2
[section1]
# 每一行作为一个 option
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31
[section2]
k1 = v1
……
'''
# import configparser
#
# # 打开配置文件,创建配置文件对象
# cfg = configparser.ConfigParser()
# # 读取一个配置文件
# cfg.read('download.ini',)
#
#
# # 查询操作:
#
# #查看所有的分区名
# res=cfg.sections() #['section1', 'section2']
# print(res)
# # 获取指定section名下的所有option名
# print(cfg.options('section1'))
# #查看指定section下的某一个已知option的值
# print(cfg.get('section1','maxSpeed'))#返回字符串
# print(cfg.getint('section1','maxSpeed'))#返回整形
# print(cfg.getfloat('section1','maxSpeed'))#返回浮点
# # print(cfg.getboolean('section1','maxSpeed'))#返回布尔
#
# #查看标题section1下所有key=value的key
# options=cfg.options('section1')
# print(options)
# #['k1', 'k2', 'user', 'age', 'is_admin', 'salary'
#
# #查看标题section1下所有key=value的(key,value)格式
# item_list=cfg.items('section1')
# print(item_list)
# #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
#
#
# # 修改配置文件内容
#
# #删除整个section2分区
# cfg.remove_section('section2')
# #删除分区section1下的某个option(k1和k2)
# cfg.remove_option('section1','k1')
# cfg.remove_option('section1','k2')
# #判断是否存在某个section
# print(cfg.has_section('section1'))
# #判断标题section1下是否有user
# print(cfg.has_option('section1',''))
# #添加一个section
# cfg.add_section('egon')
# #在标题egon下添加name=egon,age=18的配置
# # cfg.set(section名,option名,option值)
# cfg.set('egon','name','egon')
# cfg.set('egon','age','18') #报错,必须是字符串
#
# #最后将修改的内容写入文件,完成最终的修改
# cfg.write(open('download.ini','w'))
# -----------------------
# # 添加一个ini配置文件
# import configparser
#
# # 打开文件,创建一个配置文件对象
# config = configparser.ConfigParser()
# # 设置文件内属性
# # default section创建
# config["DEFAULT"] = {'ServerAliveInterval': '45',
# 'Compression': 'yes',
# 'CompressionLevel': '9'}
#
# config['bitbucket.org'] = {}
# # bitbucket.org 分区下的User option进行赋值
# config['bitbucket.org']['User'] = 'hg'
#
# config['topsecret.server.com'] = {}
# # 分步对topsecret.server.com分区下的option进行赋值
# topsecret = config['topsecret.server.com']
# topsecret['Host Port'] = '50022'
# topsecret['ForwardX11'] = 'no'
# config['DEFAULT']['ForwardX11'] = 'yes'
#
# # 写入文件
# with open('example.ini', 'w') as configfile:
# config.write(configfile)
'''
hashlib模块
1、什么叫hash: hash是一种算法
(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法)
该算法接受传入的内容,经过运算得到一串hash值
2、hash值的特点是:
2.1 只要传入的内容一样,得到的hash值必然一样;输入内容不同,的到的hash值可能相同
=====>要用明文传输密码文件完整性校验
2.2 不能由hash值返解成内容
=======》把密码做成hash值,不应该在网络传输明文密码
2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
用处:将其用于加密和文件校验
'''
# import hashlib
#
# m = hashlib.md5() # m=hashlib.sha256()
#
# m.update('hello'.encode('utf8'))
# print(m.hexdigest()) # 5d41402abc4b2a76b9719d911017c592
#
# m.update('alvin'.encode('utf8'))
# print(m.hexdigest()) # 92a7e713c30abbb0319fa07da2a5c4af
#
# m2 = hashlib.md5()
# m2.update('helloalvin'.encode('utf8'))
# print(m2.hexdigest()) # 92a7e713c30abbb0319fa07da2a5c4af
#
# '''
# 注意:把一段很长的数据update多次,与一次update这段长数据,得到的结果一样
# 但是update多次为校验大文件提供了可能。
# '''
#
# #
# # python 还有一个 hmac 模块,
# # 它内部对我们创建 key 和 内容 进行进一步的处理然后再加密:
# import hmac
# h = hmac.new('alvin'.encode('utf8'))
# h.update('hello'.encode('utf8'))
# print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940
python 配置Stream推送 python stream模块
转载本文章为转载内容,我们尊重原作者对文章享有的著作权。如有内容错误或侵权问题,欢迎原作者联系我们进行内容更正或删除文章。
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
Java之Stream流
Stream是一种处理集合(Collection)数据的方式。Stream可以让我们以一种更简洁的方式对集合进行过滤、映射、排序等操作。
System 数据 数组 Stream Java基础 -
python模块--Telnetlib模块
telnet模块
ci 用户名 for循环