Python学习笔记-常用模块

一、日志模块(logging模块)

1、日志级别

CRITICAL = 50 #严重
ERROR = 40 #错误
WARNING = 30 #警告
INFO = 20 #所有信息
DEBUG = 10 #调试
NOTSET = 0 #不需设置

2、日志模块基本用法以及全局配置

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('warn') #对应数字为30
logging.error('error')  #对应数字为40
logging.critical('critical')    #对应数字为50


执行结果:
access.log文件内容:
2018-04-30 12:02:13 PM - root - DEBUG -日志模块logging:  debug
2018-04-30 12:02:13 PM - root - INFO -日志模块logging:  info
2018-04-30 12:02:13 PM - root - WARNING -日志模块logging:  warn
2018-04-30 12:02:13 PM - root - ERROR -日志模块logging:  error
2018-04-30 12:02:13 PM - root - CRITICAL -日志模块logging:  critical
更改日志打印格式
可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
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()介绍

3、日志模块的详细用法

Logger:产生日志的对象
Filter:过滤日志的对象
Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端
Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

# 日志模块的详细用法:
import logging

# 1、Logger:产生日志
logger1=logging.getLogger('访问日志')

# 2、Filter:过滤日志,基本上不用

# 3、Handler:接受Logger传过来的日志,进行日志格式化,可以打印到终端,也可以打印到文件,FileHandler用来打印到文件中,StreamHandler用来打印到终
sh=logging.StreamHandler()
fh1=logging.FileHandler('s1.log',encoding='utf-8')
fh2=logging.FileHandler('s2.log',encoding='utf-8')

# 4、Formatter:日志格式,可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式
formatter1=logging.Formatter(
    fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p'
)

formatter2=logging.Formatter(
    fmt='%(asctime)s : %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p'
)

formatter3=logging.Formatter(
    fmt='%(asctime)s : %(module)s : %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p'
)

# 5、为handler绑定日志格式
sh.setFormatter(formatter1)
fh1.setFormatter(formatter2)
fh2.setFormatter(formatter3)

# 6、为logger绑定handler
logger1.addHandler(sh)
logger1.addHandler(fh1)
logger1.addHandler(fh2)

# 7、设置日志级别:logger对象日志级别应该小于等于handler的日志级别
logger1.setLevel(10)
sh.setLevel(10)
fh1.setLevel(10)
fh2.setLevel(10)

# 8、测试
logger1.debug('测试着玩')
logger1.info('运行还算正常')
logger1.warning('可能要有bug了')
logger1.error('不好了,真tm出bugle')
logger1.critical('完犊子,推到重写')
Logger、Filter、Handler、Formatter的使用

4、日志模块在项目中的应用

"""
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、什么是正则?

  正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

2、常用匹配模式(元字符)

import re
# 正则匹配
# \w与\W
print(re.findall('\w','lionel 123 _ - *'))
"""
['l', 'i', 'o', 'n', 'e', 'l', '1', '2', '3', '_']
"""

print(re.findall('\W','lionel 123 _ - *'))
"""
[' ', ' ', ' ', '-', ' ', '*']
"""

# \s与\S
# \n \t都是空,都可以被\s匹配
print(re.findall('\s','lionel 123 _ - *'))
"""
[' ', ' ', ' ', ' ']
"""

print(re.findall('\S','lionel 123 _ - *'))
"""
['l', 'i', 'o', 'n', 'e', 'l', '1', '2', '3', '_', '-', '*']
"""

# \d与\D
print(re.findall('\d','lionel 123 _ - *'))
"""
['1', '2', '3']
"""

print(re.findall('\D','lionel 123 _ - *'))
"""
['l', 'i', 'o', 'n', 'e', 'l', ' ', ' ', '_', ' ', '-', ' ', '*']
"""

# \n与\t
print(re.findall('\n','lione\tl 12\n3 _ - *'))
"""
['\n']
"""

print(re.findall('\t','lione\tl 12\n3 _ - *'))
"""
['\t']
"""

print(re.findall('e','lione\tl 12\n3 +hello _ - *'))
"""
['e', 'e']
"""

# ^与$
print(re.findall('^l','lione\tl 12\n3 +hello _ - *'))
"""
['l']
"""

print(re.findall('o$','lione\tl 12\n3 +hello'))
"""
['o']
"""
正则匹配
# 重复:.|?|*|+|{n,m}|.*|.*?

# .代表换行符以外任意一个字符
print(re.findall('a.b','a1b a b a-b a\nb a\tb aaaaab a123b'))
"""
['a1b', 'a b', 'a-b', 'a\tb', 'aab']
"""

# 使.匹配换行符
print(re.findall('a.b','a1b a b a-b a\nb a\tb aaaaab a123b',re.DOTALL))
"""
['a1b', 'a b', 'a-b', 'a\nb', 'a\tb', 'aab']
"""

# ?代表?左边的字符出现0次或者1次
print(re.findall('ab?','a ab abb abbbb a1b'))
"""
['a', 'ab', 'ab', 'ab', 'a']
"""

# *代表*号左边的字符出现0次或者无穷次
print(re.findall('ab*','a ab abb abbbb a1b'))
"""
['a', 'ab', 'abb', 'abbbb', 'a']
"""

# +代表+号左边的字符出现1次或者无穷次
print(re.findall('ab+','a ab abb abbbb a1b'))
"""
['ab', 'abb', 'abbbb']
"""

# {n,m}代表左边的字符出现n次或者m次
print(re.findall('ab{0,1}','a ab abb abbbb a1b'))
print(re.findall('ab{0,}','a ab abb abbbb a1b'))
print(re.findall('ab{1,}','a ab abb abbbb a1b'))
print(re.findall('ab{2,4}','a ab abb abbbb a1b'))

"""
['a', 'ab', 'ab', 'ab', 'a']
['a', 'ab', 'abb', 'abbbb', 'a']
['ab', 'abb', 'abbbb']
['abb', 'abbbb']
"""

# .*代表可以有任意个字符,贪婪匹配
print(re.findall('a.*b','xxxy123aa1a23b456b'))
"""
['aa1a23b456b']
"""

# .*?代表可以有任意个字符,非贪婪匹配
print(re.findall('a.*?b','xxxy123aa1a23b456b'))
"""
['aa1a23b']
"""

# |代表或者
print(re.findall('compan(y|iess)','Too many companiess have gone bankrupt, and the next one is my company'))    # findall的结果不是匹配的全部内容,而是组内的内容
"""
['iess', 'y']
"""

print(re.findall('compan(?:y|iess)','Too many companiess have gone bankrupt, and the next one is my company'))  # findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
"""
['companiess', 'company']
"""

# ()代表分组
print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击我</a>'))
"""
['http://www.baidu.com']
"""

# rawstring:反斜杠的匹配
print(re.findall(r'a\\c','a\c a1c aBc'))
"""
['a\\c']
"""

# []:取中括号内任意的一个
print(re.findall('a[a-z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[A-Z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[a-zA-Z]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[0-9]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[-+*/]b','axb azb aAb a1b a-b a+b'))
print(re.findall('a[^-+*/]b','axb azb aAb a1b a-b a+b'))

"""
['axb', 'azb']
['aAb']
['axb', 'azb', 'aAb']
['a1b']
['a-b', 'a+b']
['axb', 'azb', 'aAb', 'a1b']
"""
重复匹配
# re模块的其他方法
# re.search:只匹配成功一次就返回
print(re.search('a[*]b','axb azb aAb a1b a-b a+b'))
print(re.search('a[0-9]b','axb azb aAb a1b a-b a+b').group())
"""
None
a1b
"""

# re.match:从开头取
print(re.match('a[0-9]b','axb azb aAb a1b a-b a+b'))
print(re.match('a[0-9]b','a1b axb azb aAb a1b a-b a+b').group())
print(re.search('^a[0-9]b','a1b axb azb aAb a1b a-b a+b').group())
"""
None
a1b
a1b
"""

# re.split:切割
print(re.split(':','root:x:0:0::/root:/bin/bash'))
print(re.split(':','root:x:0:0::/root:/bin/bash',maxsplit=1))
"""
['root', 'x', '0', '0', '', '/root', '/bin/bash']
['root', 'x:0:0::/root:/bin/bash']
"""

# re.sub:替换
print(re.sub('root','admin','root:x:0:0::/root:/bin/bash'))
print(re.sub('root','admin','root:x:0:0::/root:/bin/bash',1))
print(re.sub('^([a-zA-Z]+)([^a-zA-Z]+)(.*?)([^a-zA-Z]+)([a-zA-Z]+)$',r'\5\2\3\4\1','root:x:0:0::/root:/bin/bash'))

"""
admin:x:0:0::/admin:/bin/bash
admin:x:0:0::/root:/bin/bash
bash:x:0:0::/root:/bin/root
"""

# re.compile:正则重复使用
obj=re.compile('a\d{2}b')
print(obj.search('a12b a123b a12345b abbb').group())
"""
a12b
"""
re模块的其他方法

三、时间模块(time与datetime模块)

time模块

1、Python中常用的几种表示时间的方式

  • 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量。我们运行“type(time.time())”,返回的是float类型。
  • 格式化的时间字符串(Format String)
  • 结构化的时间(struct_time):struct_time元组共有9个元素共九个元素:(年,月,日,时,分,秒,一年中第几周,一年中第几天,夏令时)
import time
# time.time():时间戳
print(time.time())
"""
1525066587.904426
"""

# time.localtime():本地时区
print(time.localtime())
"""
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=30, tm_hour=13, tm_min=36, tm_sec=27, tm_wday=0, tm_yday=120, tm_isdst=0)
"""

print(time.localtime().tm_mday) #本月的第几天
"""
30
"""

# time.gmtime():标准时区,UTC时区
print(time.gmtime())
"""
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=30, tm_hour=5, tm_min=36, tm_sec=27, tm_wday=0, tm_yday=120, tm_isdst=0)
"""

# time.strftime():格式化时间
print(time.strftime('%Y-%m-%d %H:%M:%S'))
print(time.strftime('%Y-%m-%d %X'))
print(time.strftime('%Y-%m-%d %T'))

"""
2018-04-30 13:36:27
2018-04-30 13:36:27
2018-04-30 13:36:27
"""
View Code

  计算机认识的时间只能是'时间戳'格式,而程序员可处理的或者说人类能看懂的时间有: '格式化的时间字符串','结构化的时间' ,于是有了下图的转换关系

# 结构化的时间转换成时间戳
print(time.mktime(time.localtime()))
"""
1525066881.0
"""

# 把结构化的时间转化成格式化的字符串时间
print(time.strftime('%Y-%m-%d',time.localtime()))
"""
2018-04-30
"""

# 把格式化的字符串时间转化成结构化的时间
print(time.strptime('2017-03-01','%Y-%m-%d'))
"""
time.struct_time(tm_year=2017, tm_mon=3, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=60, tm_isdst=-1)
"""

# 把一个表示时间的元组或者struct_time表示为这种形式:'Sun Jun 20 23:21:05 1993'。如果没有参数,将会将time.localtime()作为参数传入
print(time.asctime(time.localtime()))
"""
Mon Apr 30 13:45:46 2018
"""

# 把一个时间戳(按秒计算的浮点数)转化为time.asctime()的形式。如果参数未给或者为None的时候,将会默认time.time()为参数。它的作用相当于time.asctime(time.localtime(secs))。
print(time.ctime(11111))
"""
Thu Jan  1 11:05:11 1970
"""
时间转换

datetime模块

import datetime
# 1、返回 2016-08-19 12:47:03.941925
print(datetime.datetime.now()) 
"""
2018-04-30 13:49:04.906509
"""

# 2、时间戳直接转成日期格式 2016-08-19
print(datetime.datetime.fromtimestamp(1111111)) 
"""
1970-01-14 04:38:31
"""

# 3、当前时间+3天
print(datetime.datetime.now()+datetime.timedelta(days=3)) 
"""
2018-05-03 13:50:42.421749
"""

# 4、当前时间-3天
print(datetime.datetime.now()+datetime.timedelta(days=-3))
"""
2018-04-27 13:52:45.272195
"""

# 5、当前时间+3小时
print(datetime.datetime.now()+datetime.timedelta(hours=3))
"""
2018-04-30 16:53:32.638284
"""

# 6、当前时间+3分钟
print(datetime.datetime.now()+datetime.timedelta(minutes=3))
"""
2018-04-30 13:57:34.481887
"""

# 7、当前时间+3秒
print(datetime.datetime.now()+datetime.timedelta(seconds=3))
"""
2018-04-30 13:54:37.481932
"""

# 8、时间替换
print(datetime.datetime.now().replace(year=1999,hour=12))
"""
1999-04-30 12:55:40.772420
"""
datetime模块,加减时间

四、生成随机数模块(random模块)

# 取0-1之间的小数
print(random.random())
"""
0.37416550989635244
"""

# 取大于等于1且小于等于3之间的整数
print(random.randint(1,3))
"""
3
"""

# 取大于等于1且小于3之间的整数
print(random.randrange(1,3))
"""
2
"""

# 取列表或元祖中任意一个
print(random.choice([1,'lionel',2]))
"""
lionel
"""

# 取列表或元祖中任意两个
print(random.sample([1,'lionel',2],2))
"""
['lionel', 2]
"""

# 取大于1小于4的小数
print(random.uniform(1,4))
"""
1.7474791050101217
"""

# 打乱列表顺序
l=[1,2,3,4,5]
random.shuffle(l) # 打乱顺序,相当于"洗牌"
print(l)

"""
[5, 1, 4, 3, 2]
"""

# 生成随机验证码
def make_code(n):
    res=''
    for i in range(n):
        s1 = str(random.randint(0,9)) # 数字
        s2 = chr(random.randint(65,90)) # 大写字母
        res += random.choice([s1,s2])
    return res
print(make_code(4))

"""
ZX6P
"""
random模块

五、os模块

# os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
# os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd
# os.curdir  返回当前目录: ('.')
# os.pardir  获取当前目录的父目录字符串名:('..')
# 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.stat('path/filename')  获取文件/目录信息
# os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
# os.linesep    输出当前平台使用的行终止符,win下为"\r\n",Linux下为"\n"
# os.pathsep    输出用于分割文件路径的字符串 win下为';',Linux下为':'
# os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
# os.system("bash command")  运行shell命令,直接显示
# os.environ  获取系统环境变量
# 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.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
# os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
# os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间
# os.path.getsize(path) 返回path的大小
# os.path.normpath(path) 规范化路径,如..和/
os模块常用介绍
import os
BASE_DIR = os.path.normpath(os.path.join(
    os.path.abspath(__file__),
    '..',
    '..'
))
print(BASE_DIR)

"""
/Users/wangzhiwei/python/day6
"""
os路径处理,方法一:推荐使用
import os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(BASE_DIR)

"""
/Users/wangzhiwei/python/day6
"""
os路径处理,方法二:不推荐使用

六、sys模块

# sys.argv           命令行参数List,第一个元素是程序本身路径
# sys.exit(n)        退出程序,正常退出时exit(0)
# sys.version        获取Python解释程序的版本信息
# sys.maxint         最大的Int值
# sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
# sys.platform       返回操作系统平台名称
import time

def progress(percent,width=50):
    if percent > 1:
        percent = 1
    show_str = ('[%%-%ds]' %width) %('#' * int(width*percent))
    print('\r%s %d%%' %(show_str,int(100*percent)),end='')

recv_size=0
total_size=102410
while recv_size < total_size:
    time.sleep(0.1)
    recv_size+=1024
    progress(recv_size/total_size)

"""
[##################################################] 100%
"""
打印进度条

七、zipfile与tarfile模块

import zipfile

# 压缩
z = zipfile.ZipFile('yasuo.zip', 'w')
z.write('access.log')
z.write('error.log')
z.close()

# 解压
z = zipfile.ZipFile('yasuo.zip', 'r')
z.extractall(path='.')
z.close()
zipfile压缩及解压
import tarfile

# 压缩
>>> t=tarfile.open('/tmp/yasuo.tar','w')
>>> t.add('/test1/a.py',arcname='a.bak')
>>> t.add('/test1/b.py',arcname='b.bak')
>>> t.close()

# 解压
>>> t=tarfile.open('/tmp/yasuo.tar','r')
>>> t.extractall('/yasuo')
>>> t.close()
tarfile压缩及解压

八、序列化与反序列化

1、什么是序列化

  我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。

2、为什么要序列化

  (1)持久保存状态

  (2)跨平台数据交互

3、json的使用

# json.dumps()用于将dict类型的数据转成str,因为如果直接将dict类型的数据写入json文件中会发生报错,因此在将数据写入时需要用到该函数。
import json,time
user={'name':'lionel','age':18,'nb':'True'}
with open('user.json','w',encoding='utf-8') as f:
    f.write(json.dumps(user))

students=['alex','egon','lionel']
json.dump(students,open('students.json','w',encoding='utf-8'))

time.sleep(500)
json序列化
import json
# 方法一:
with open('user.json','r',encoding='utf-8') as f:
    user=json.loads(f.read())
    print(user['name'])

# 方法二:
user=json.load(open('user.json','r',encoding='utf-8'))
print(user['name'])
json反序列化

4、pickle的使用

import pickle
s={1,2,3,4}
pickle.dump(s,open('s.pkl','wb'))
pickle序列化
import pickle
# 方法一:
with open('s.pkl','rb') as f:
    s=pickle.loads(f.read())
    print(s,type(s))

# 方法二:
s=pickle.load(open('s.pkl','rb'))
print(s,type(s))
pickle反序列化

九、xml模块

1、xml数据格式

<data v="1.0">
    xxxxx
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>
xml数据

2、xml简单使用

from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
print(root.tag) # 标签的名字
print(root.attrib) # 标签属性,以字典形式显示
print(root.text) # 标签文本

"""
data
{'v': '1.0'}

    xxxxx
"""
View Code

3、xml三种查找方式

(1)从子节点中查找

from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
print(root.find('country')) # 在root的子节点找,只找一个
print(root.findall('country')) # 在root的子节点找,找所有

"""
<Element 'country' at 0x1005b2c78>
[<Element 'country' at 0x1005b2c78>, <Element 'country' at 0x101d92458>, <Element 'country' at 0x101d92638>]
"""
从子节点中查找

(2)从正树形结构中查找

from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
print(root.iter('rank')) # 全文搜索,得到迭代器,使用list查看
print(list(root.iter('rank'))) # 全文搜索

"""
<_elementtree._element_iterator object at 0x1026ae4c0>
[<Element 'rank' at 0x1026656d8>, <Element 'rank' at 0x1026ad4a8>, <Element 'rank' at 0x1026ad688>]
"""

# 找出所有rank信息
from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
for country in root.findall('country'):
    rank=country.find('rank')
    print(rank.tag,rank.attrib,rank.text)

"""
rank {'updated': 'yes'} 2
rank {'updated': 'yes'} 5
rank {'updated': 'yes'} 69
"""
从正树形结构中查找

(3)遍历文档树

from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
for country in root:
    print('==========>',country.attrib['name'])
    for item in country:
        print(item.tag,item.attrib,item.text)

"""
==========> Liechtenstein
rank {'updated': 'yes'} 2
year {} 2008
gdppc {} 141100
neighbor {'direction': 'E', 'name': 'Austria'} None
neighbor {'direction': 'W', 'name': 'Switzerland'} None
==========> Singapore
rank {'updated': 'yes'} 5
year {} 2011
gdppc {} 59900
neighbor {'direction': 'N', 'name': 'Malaysia'} None
==========> Panama
rank {'updated': 'yes'} 69
year {} 2011
gdppc {} 13600
neighbor {'direction': 'W', 'name': 'Costa Rica'} None
neighbor {'direction': 'E', 'name': 'Colombia'} None
"""

# 全文搜索year信息
from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
for year in root.iter('year'):
    print(year.tag,year.attrib,year.text)

"""
year {} 2008
year {} 2011
year {} 2011
"""
遍历文档树

4、xml的修改

from xml.etree import ElementTree

tree = ElementTree.parse('a.xml')
root=tree.getroot()
for year in root.iter('year'):
    year.set('updated','yes')
    year.text=str(int(year.text)+1)
tree.write('b.xml')
xml修改

5、xml添加节点

from xml.etree import ElementTree
tree = ElementTree.parse('a.xml')
root=tree.getroot()
# 在country节点下添加节点
for country in root:
    obj=ElementTree.Element('lionel') #<lionel name="lionel" age="18">lionel is good </lionel>
    obj.attrib={'name':'lionel','age':'18'}
    obj.text='lionel is good'
    country.append(obj)
tree.write('a.xml')
# 在rank节点下添加节点
for rank in root.iter('rank'):
    if int(rank.text) == 5:
        obj=ElementTree.Element('wang')
        obj.attrib={'name':'wang','age':'20'}
        obj.text='wang is good'
        rank.append(obj)
tree.write('a.xml')
xml添加节点

6、自建xml文档

import xml.etree.ElementTree as ET

new_xml = ET.Element("namelist")
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("test.xml", encoding="utf-8", xml_declaration=True)

ET.dump(new_xml)  # 打印生成的格式
View Code

十、configerparser模块

[mysqld]
charater-server-set = utf-8
default-engine = innodb
skip-grant-table = True
port = 3306

[client]
user = root
password = "123456"
my.cnf配置
import configparser
config=configparser.ConfigParser()
config.read('my.cnf')

# 查看所有的标题
print(config.sections())
"""
['mysqld', 'client']
"""

# 判断有没有mysqld这个标题
print(config.has_section('mysqld'))
"""
True
"""

# 查看标题mysqld下所有key=value的key
print(config.options('mysqld'))
"""
['charater-server-set', 'default-engine', 'skip-grant-table', 'port']
"""

# 判断mysqld标题下,有没有aaa这一项
print(config.has_option('mysqld','aaa'))
"""
False
"""

# 查看标题mysqld下port的值=>字符串格式
print(config.get('mysqld','port'))
"""
3306
"""

# 查看标题mysqld下skip-grant-table的值=>布尔值格式
print(config.getboolean('mysqld','skip-grant-table'))
"""
True
"""

# 查看标题mysqld下port的值=>整数格式
print(config.getint('mysqld','port'))
"""
3306
"""

# 查看标题mysqld下port的值=>浮点型格式
print(config.getfloat('mysqld','port'))
"""
3306.0
"""
读取my.cnf每项配置
# 1、添加
import configparser
config=configparser.ConfigParser()
config.read('my.cnf')

config.add_section('mysqld_safe')
config.set('mysqld_safe','log-error','/data/mysql/mysql.err')
config.set('mysqld_safe','pid-file','/data/mysql/mysqld.pid')
config.write(open('my.cnf','w',encoding='utf-8'))

# 2、修改
import configparser
config=configparser.ConfigParser()
config.read('my.cnf')

config.set('client','password','"123123"')
config.write(open('my.cnf','w',encoding='utf-8'))
更改my.cnf配置
import configparser

config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                     'Compression': 'yes',
                     'CompressionLevel': '9'}

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'
topsecret['ForwardX11'] = 'no'
config['DEFAULT']['ForwardX11'] = 'yes'
config.write(open('example.cnf','w',encoding='utf-8'))
自定义cnf配置文件

十一、hashlib模块

1、什么叫hash?

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

2、hash值的特点

  • 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验
  • 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码
  • 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定
    import hashlib
    # 用法一:把字符串拆分计算hash值
    m=hashlib.md5()
    m.update('hello'.encode('utf-8'))
    m.update('world'.encode('utf-8'))
    print(m.hexdigest())
    """
    fc5e038d38a57032085441e7fe7010b0
    """
    
    # 用法二:直接计算字符串hash值
    m=hashlib.md5()
    m.update('helloworld'.encode('utf-8'))
    print(m.hexdigest())
    """
    fc5e038d38a57032085441e7fe7010b0
    """
    View Code

3、hashlib的使用

import hashlib
# 用法一:把字符串拆分计算hash值
m=hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
print(m.hexdigest())
"""
fc5e038d38a57032085441e7fe7010b0
"""

# 用法二:直接计算字符串hash值
m=hashlib.md5()
m.update('helloworld'.encode('utf-8'))
print(m.hexdigest())
"""
fc5e038d38a57032085441e7fe7010b0
"""

# 对用户输入的密码进行打印
import hashlib
name=input('user:>> ')
pwd=input('password:>> ')
m=hashlib.md5(pwd.encode('utf-8'))
pwd=m.hexdigest()
print(name,pwd)
"""
user:>> lionel
password:>> 123456
lionel e10adc3949ba59abbe56e057f20f883e
"""
hashlib模块简单使用
# 方法一:
import hashlib
m=hashlib.md5('天王盖地虎'.encode('utf-8'))
m.update('123456'.encode('utf-8'))
m.update('宝塔镇河妖'.encode('utf-8'))
print(m.hexdigest())
"""
868d1d89b3c3d1d0c02a92c576258091
"""

# 方法二:
import hmac
m=hmac.new('kkk'.encode('utf-8'))
m.update('123456'.encode('utf-8'))
print(m.hexdigest())
"""
e7977b6fda4b8593617a428745d8b7b7
"""
密码加严

十二、subprocess模块

1、什么是subprocess模块?

  subprocess的目的就是启动一个新的进程并且与之通信。subprocess模块中定义了一个Popen类,通过它可以来创建进程,并与其进行复杂的交互。

# 1、命令正确
import subprocess
obj=subprocess.Popen('uptime',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )
print('-------->主')
print(obj.stdout.read().decode('utf-8'))
"""
-------->主
14:13  up  2:45, 1 user, load averages: 2.19 1.78 1.69
"""

# 2、命令错误
import subprocess
obj=subprocess.Popen('psss -ef',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj.stdout.read())
print(obj.stderr.read().decode('utf-8'))
"""
b''
/bin/sh: psss: command not found
"""
subprocess模块简单使用
import subprocess
obj=subprocess.Popen('ps -ef|grep python|grep -v grep',
                 shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj.stdout.read().decode('utf-8'))
"""
root      1006     1  0  2017 ?        00:30:54 /usr/bin/python -Es /usr/sbin/tuned -l -P
lionel   26755 26648  0 14:19 pts/0    00:00:00 python3 09_subprocess模块.py
"""

import subprocess
obj1=subprocess.Popen('ps -ef',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

obj2=subprocess.Popen('grep python',shell=True,
                 stdin=obj1.stdout,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

obj3=subprocess.Popen('grep -v grep',shell=True,
                 stdin=obj2.stdout,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj3.stdout.read().decode('utf-8'))
"""
root      1006     1  0  2017 ?        00:30:54 /usr/bin/python -Es /usr/sbin/tuned -l -P
lionel   26755 26648  0 14:19 pts/0    00:00:00 python3 09_subprocess模块.py
"""
了解

猜你喜欢

转载自www.cnblogs.com/wangzhiwei10/p/8813901.html