代码改变世界

Python006-常用模块

2018-04-19 06:57  Ashome123  阅读(155)  评论(0)    收藏  举报
一、 模块
  - import module_alex:本质是将模块module_alex解释,运行了一遍,将结果传给当前脚本的变量module_alex
  - from module_alex import name:将module_alex的name变量运行一遍,将结果传给当前脚本变量name
  - 导入package:解释运行package里的__init__.py文件,__init__.py里的内容可以被导入执行
  - 在__init__导入包里的脚本文件,外部脚本import包时即可导入包内所有的文件
  - from . import test1——从当前目录下导入test1
  - 用from比直接import效率高
from web import logger                      # 从同目录下的web包里引入logger模块
logger.logger_func()                        # 调用logger模块里的logger_func函数

from web.logger import logger_func          # 从同目录下的web包里的logger模块引入logger_func函数
logger_func()                               # 直接调用logger_func函数

from web.logger import logger_func as l     # 从web包里的logger模块引入logger_func函数,并起别名为l
l()


from web.web2 import logger2                # 从web包里的web2包里引入logger2模块
logger2.logger_func2()

from web.web2.logger2 import logger_func2   # 从web包里的web2包里的logger2模块引入logger_func2函数
logger_func2()

 



二、  时间模块——time和datetime
  time.time():时间戳,从1970年开始计算的秒数
import time,datetime

a = time.time()                     # 时间戳
print('时间戳a:',a)                  # 1524090451.8660543

 


  time.timezone:标准时区跟当地时区相差的秒数
  time.altzone:标准时区跟夏令时的差值
  time.daylight:是否使用了夏令时,没有使用返回0
  time.gmtime():传入时间戳,将时间戳转换成struct_time格式,不传入参数则返回标准时区现在的时间
import time,datetime

a = time.time()                     # 时间戳
print('时间戳a:',a)                  # 1524090451.8660543

b = time.gmtime()                   # 中央时区当前时间,结构化struct_time格式
print('中央时区当前时间b:',b)   # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=18, tm_hour=22, tm_min=27, tm_sec=31, tm_wday=2, tm_yday=108, tm_isdst=0)

b = time.gmtime(a)                   # 传入时间戳,将时间戳转换成结构化struct_time格式
print('中央时区当前时间b:',b)          # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=18, tm_hour=22, tm_min=50, tm_sec=56, tm_wday=2, tm_yday=108, tm_isdst=0)
 
 

  time.localtime():传入时间戳,将时间戳转换成struct_time格式,不传入参数则返回当地时区现在的时间
import time,datetime

c = time.localtime()          #本地时区当前时间,结构化struct_time格式
print('本地时区当前时间c:',c)   # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=19, tm_hour=6, tm_min=27, tm_sec=31, tm_wday=3, tm_yday=109, tm_isdst=0)
print(c.tm_year)         # 2018

 




  time.mktime(c):将struct_time格式转换为时间戳
print(time.mktime(c))    #1524092315.0

 


  time.strftime('%Y-%m-%d %H:%M:%S',struct_time格式c):将struct_time格式转换成自定义格式化时间
  time.strptime(格式化时间s, '%Y-%m-%d %H:%M:%S'):返回struct_time格式c
d = time.strftime('%Y-%m-%d %H:%M:%S',c)    # 把struct_time格式转化成自定义格式
print('d:',d)                               # 2018-04-19 06:27:31

e = time.strptime(d,'%Y-%m-%d %H:%M:%S')    # 把自定义格式转化成struct_time格式
print('e:',e)   # time.struct_time(tm_year=2018, tm_mon=4, tm_mday=19, tm_hour=6, tm_min=27, tm_sec=31, tm_wday=3, tm_yday=109, tm_isdst=-1)

 

 

 

    time.ctime(时间戳):不传参数返回当地时区当前时间,传入时间戳返回一个格式的时间形式

 

    time.asctime(tuple):不传参数返回当地时区当前时间,传入元祖返回一个格式化的时间形式

 

f = time.ctime(a) # 传入时间戳,转换成某种指定格式
print('f:',f)     # Thu Apr 19 06:27:31 2018

g = time.asctime(c) # 传入struct_time,转换成某种指定格式
print('g:',g)       # Thu Apr 19 06:27:31 2018

 

 


 



         datetime.datetime.now():获取当前时间

 

h = datetime.datetime.now()
print(h)            # 2018-04-19 06:27:31.868096

 

 


    datetime.datetime.now()+ datetime.timedelta(3):返回3天后的时间
    datetime.datetime.now()+ datetime.timedelta(hour=3):返回3小时后的时间

    c_time = datetime.datetime.now()
    print(c_time.replace(minute=3,hour=2))把当前的时间替换

 

 

三、random模块
random.random():随机返回0到1之间的浮点数
random.randint(1,3):随机返回1到3之间的整数
random.randrange(1,3):随机返回1到2之间的整数
random.choice(序列):随机返回序列里的一个值
import random

a = 'abcdefg'
print(random.choice(a))

 


random.sample(序列,2):从序列中随机取两位,返回一个列表
random.uniform(1,10):随机返回1到10内之间的浮点数
random.shuffle(list):打乱原来的列表list


四、OS模块
os.getcwd():获取当前的操作目录
os.chdir('C:\\Users'):切换目录
os.curdir:返回当前目录.
os.pardir:返回上一级目录..
os.makedirs(r'C:\a\b\c\d'):生成多层递归目录
os.removedirs(r'C:\a\b\c\d'):若目录为空,则删除并递归到上一级目录,若上一级也为空,则持续删除
os.mkdir():不能生成多层递归目录
os.rmdir():只删除一层
os.listdir('.'):以列表形式列出当前目录所有文件
os.remove():删除一个文件
os.rename('oldname','newname'):重命名文件和目录
os.stat(path\文件名):返回一个元祖,该文件的信息
os.sep:返回操作系统路径分隔符
os.linesep:换行符
os.pathsep:存放多个路径的分隔符
os.envion:返回包含系统环境变量的字典
os.name:返回当前操作系统名称
os.system('ipconfig /all'):返回操作系统命令
os.path.abspath():获取绝对路径

os.path.split(r'C:\a\b\c\d.txt'):返回一个二元组,第一个是路径,第二个是文件名
os.path.dirname(path):返回path的目录,os.path.split元祖的第一个元素
os.path.basename(path):返回path的文件名,os.path.split元祖的第二个元素

os.path.exist(r'C:'):判断路径是否存在

os.path.isabs(path):判断是否绝对路径
os.path.isfile(path):判断是否文件
os.path.isdir(path):判断是否目录

os.path.join('C:\\','a','b','a.txt'):将多个路径拼接返回
os.path.getatime(path):返回path的文件或目录最后存取时间
os.path.getmtime(path):返回path的文件或目录最后修改时间

五、sys模块
sys.argv:返回list,第一个元素是程序本身路径,后面是输入的参数
sys.exit(n):退出程序,正常退出时exit(0)
sys.version:获取python解释器版本信息
sys.maxint:最大的int值
sys.path:返回模块的搜索路径,初始化时使用pythonpath环境变量的值
sys.platform:返回操作系统平台名称
sys.stdout.write('please:'):标准输出

获取当前相对路径:__file__
获取当前绝对路径:os.path.abspath(__file__)
获取目录去掉文件名(即获取上一级目录):os.path.dirname()
添加到环境变量sys.path.append()



六、hashlib加密模块

import hashlib

# md5加密
m = hashlib.md5()
print(m)                        # 对象<md5 HASH object @ 0x0000018CCCB3B760>
m.update(b'Hello')
print(m.hexdigest())            # 十六进制加密:8b1a9953c4611296a827abf8c47804d7

m.update(b'It\'s me')           # 输出第一句 + 第二句
print(m.hexdigest())            # 5ddeb47b2f925ad0bf249c52e342728a

print('十进制:',m.digest())     # 十进制加密:b']\xde\xb4{/\x92Z\xd0\xbf$\x9cR\xe3Br\x8a'

n = hashlib.md5()
n.update('Hello'.encode('utf8'))# 可将中文转换为字节形式
print(n.hexdigest())

# sha加密
s2 = hashlib.sha1()
s2.update(b"HelloIt's me")
print('sha加密:',s2.hexdigest())           # 4ca1ebbeaf8237d6d1650daad5ddaeca8e9a0e4c

 

七、logging日志模块
级别从低到高排列:
logging.debug('debug message')
logging.info(('info message'))
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

logging.basicConfig()函数的参数:
filename:用指定的文件名创建FiledHandler,日志存储在指定的文件中
filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”追加模式,还可指定为“w”
format:指定handler使用的日志显示格式
datefmt:指定日期时间格式
level:设置rootlogger的日志级别
stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默认为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.debug('debug message')    #默认级别不够,不打印
# logging.info(('info message'))    #默认级别不够,不打印
# logging.warning('warning message')
# logging.error('error message')
# logging.critical('critical message')

logging.basicConfig(
        level=logging.DEBUG,    # 调整显示级别为debug,一定要大写
        format='【%(asctime)s】%(filename)s[line:%(lineno)d]【%(levelname)s】%(message)s',
        datefmt='%a, %d %b %Y %H:%M:%S',        # a是星期,b是月份缩写
        # filename='test.log',    #生成文件,不打印,加上这句不在屏幕上输出,在生成文件'test.log'里显示
        filemode='w'            #默认'a',追加模式
        )                       #写入文件

# 输出在屏幕上和输出在文件里不能同时调用
print('-------------------------------')
logging.debug('hello,debug')
logging.info(('info message2'))
logging.warning('warning message2')
logging.error('error message2')
logging.critical('critical message2')

#### 显示如下:
# 【Thu, 19 Apr 2018 08:05:27】logging1.py[line:19]【DEBUG】hello,debug
# 【Thu, 19 Apr 2018 08:05:27】logging1.py[line:20]【INFO】info message2
# 【Thu, 19 Apr 2018 08:05:27】logging1.py[line:21]【WARNING】warning message2
# 【Thu, 19 Apr 2018 08:05:27】logging1.py[line:22]【ERROR】error message2
# 【Thu, 19 Apr 2018 08:05:27】logging1.py[line:23]【CRITICAL】critical message2
import logging

####可同时输出到屏幕和文件内

#创建logger对象
logger = logging.getLogger('mylogger')      #日志对象,不加参数默认是root
#logger = logging.Logger('mylogger',level=logging.INFO)

# 创建一个handler,用于写入日志文件
fh = logging.FileHandler('test_logger.log',
                         encoding='utf8',
)       #写到文件里

# 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler() #输出到屏幕

formatter = logging.Formatter('【%(asctime)s】%(name)s-%(levelname)s-%(message)s') # 设置格式

# 把格式对象传给handler
fh.setFormatter(formatter)
ch.setFormatter(formatter)

#logger对象可以添加多个fh和ch对象
logger.addHandler(fh)
logger.addHandler(ch)

logger.setLevel(logging.DEBUG) # 设置级别

logger.debug('logger debug message')
logger.info('logger info message')
logger.warning('logger warning message')
logger.error('logger error message')
logger.critical('logger critical message')

####输出如下:
# 【2018-04-19 08:12:08,514】mylogger-DEBUG-logger debug message
# 【2018-04-19 08:12:08,514】mylogger-INFO-logger info message
# 【2018-04-19 08:12:08,514】mylogger-WARNING-logger warning message
# 【2018-04-19 08:12:08,514】mylogger-ERROR-logger error message
# 【2018-04-19 08:12:08,514】mylogger-CRITICAL-logger critical message
####logging日志模块在还款系统的应用

import os
import time
import logging
from config import settings


def get_logger(card_num, struct_time):

    if struct_time.tm_mday < 23:    # 如果日期小于23号
        file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon, 22)   # file_name = xx年xx月22日
    else:
        file_name = "%s_%s_%d" %(struct_time.tm_year,struct_time.tm_mon+1, 22)  # file_name = xx年xx+1月22日

    file_handler = logging.FileHandler(
        os.path.join(settings.USER_DIR_FOLDER, card_num, 'record', file_name),  # 在指定路径生成文件名
        encoding='utf-8'
    )
    fmt = logging.Formatter(fmt="%(asctime)s :  %(message)s")
    file_handler.setFormatter(fmt)

    logger1 = logging.Logger('user_logger', level=logging.INFO)         #另一种声明logger对象方法
    logger1.addHandler(file_handler)
    return logger1

 

 八、configparser配置文件模块
####创建配置文件
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'

# 创建配置文件
with open('example.ini', 'w') as configfile:
    config.write(configfile)

'''
输出如下:
[DEFAULT]
serveraliveinterval = 45
compression = yes
compressionlevel = 9
forwardx11 = yes

[bitbucket.org]
user = hg

[topsecret.server.com]
host port = 50022
forwardx11 = no
'''

#### 操作配置文件
import configparser

config2 = configparser.ConfigParser()

# 读取配置文件
config2.read('example.ini')     # 从文件读取

print(config2.default_section)  # 返回default_section名:DEFAULT
print(config2.sections())       # 返回非default_section名:['bitbucket.org', 'topsecret.server.com']
print(config2.defaults())       # 返回一个OrderedDict有序字典,里面的元素是default里的键值对。
'''
输出如下:
OrderedDict([('serveraliveinterval', '45'), 
            ('compression', 'yes'), 
            ('compressionlevel', '9'), 
            ('forwardx11', 'yes')]
            )
'''

# 判断section名是否在文件内
print('bitbucket.org' in config2)           # 存在返回True,否则返回False

# 取值
print(config2['bitbucket.org']['User'])     # hg

# 遍历打印
print('---------------------')
for key in config2:
    print(key)          # 打印section名:
'''
输出如下:
DEFAULT
bitbucket.org
topsecret.server.com
'''

print('---------------------')
for key in config2['bitbucket.org']:
    print(key)          # 打印[bitbucket.org]和[DEFAULT]里的所有key
print('---------------------')
'''
输出如下:
user
serveraliveinterval
compression
compressionlevel
forwardx11
'''

# 删除
config2.remove_section('topsecret.server.com')      # 删除section
config2.remove_option('bitbucket.org','user')       # 删除键值对

# 判断是否有这个section名
sec = config2.has_section('compression')            # False
sec2 = config2.has_section('bitbucket.org')         # True
print(sec,sec2)

# 添加section
sec = config2.add_section('Tony')

# 修改
config2.set('Tony','k1','11111')    # 把k1的值改成11111,section名必须存在,不能真正的改,只能覆盖

config2.write(open('i.cfg','w'))    # 写入另一个文件或者覆盖原文件

 

 

九、XML模块
  XML是一种标记语言,类似HTML。用以传输和存储数据,HTML用来显示数据

 

####创建XML
import xml.etree.ElementTree as ET

new_xml = ET.Element("personlist")      # 创建一个根标签
personinfo = ET.SubElement(new_xml, "personinfo", attrib={"enrolled": "yes"})   # 创建一个子标签
name = ET.SubElement(personinfo,'name')
name.text = 'Alex Li'   # 给标签添加文本内容
age = ET.SubElement(personinfo, "age", attrib={"checked": "no"})
sex = ET.SubElement(personinfo, "sex")
sex.text = ''

personinfo2 = ET.SubElement(new_xml, "personinfo2", attrib={"enrolled": "no"})
name = ET.SubElement(personinfo2,'name')
age = ET.SubElement(personinfo2, "age")
age.text = '19'

et = ET.ElementTree(new_xml)  # 生成文档对象
et.write("test.xml", encoding="utf-8", xml_declaration=True)

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

'''
生成如下:
<?xml version='1.0' encoding='utf-8'?>
<personlist>
    <personinfo enrolled="yes">
        <name>Alex Li</name>
        <age checked="no" />
        <sex>男</sex>
    </personinfo>
    
    <personinfo2 enrolled="no"><name />
        <age>19</age>
    </personinfo2>
</personlist>
'''

 

####处理XML
import xml.etree.ElementTree as ET

tree = ET.parse("xmltest.xml")  # 解析一个xml文件
root = tree.getroot()   # 获取最外层的标签
print('root:',root)     # 打印根节点data的对象:<Element 'data' at 0x00000203A5C18598>
print(root.tag)         # 打印根节点标签名称:data

# 遍历xml文档
print('-------------')
for child in root:      # data下的标签
    print(child.tag, child.attrib)  # country {'name': 'Liechtenstein'}
    for i in child:
        print(i.tag, i.text)
        '''
        输出如下:
        rank 2
        year 2010
        gdppc 141100
        neighbor None
        neighbor None
        '''

# 只遍历year节点
print('-------------')
for node in root.iter('year'):  # 找出data下的‘year’标签
    print(node.tag, node.text)  # year 2010

# 修改
print('-------------')
for node in root.iter('year'):
    new_year = int(node.text) + 1
    node.text = str(new_year)   # 更改文本内容
    node.set("updated", "yes")  # 给标签增加属性

tree.write("xmltest.xml")

# 删除node
print('-------------')
for country in root.findall('country'):     # 找到所有country标签
    rank = int(country.find('rank').text)
    if rank > 50:
        root.remove(country)                # 找到上一层标签root,把rank文本大于50的country标签删除

tree.write('output.xml')
'''
生成如下:
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year updated="yes">2013</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year updated="yes">2016</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    </data>
'''

 

 十、shelve模块

####生成shelve文件

# 比pickle简单,只有一个open函数,返回类似字典的对象,可读可写。值可以是python支持的数据类型
# 与pickle的主要区别是键值对方式, 并且在目录下生成三个文件
import shelve,datetime

f = shelve.open('shelve_test',writeback=True) # 开了writeback,多层嵌套的字典的value才可以被修改

# 增加
f['info']={
    'name':'alex',
    'age':'18'
}

data = f.get('info')        # {'name': 'alex', 'age': '18'}
data2 = f.get('shopping')   # None
print('data:',data)
print('data2:',data2)

f['aaa'] = 2  # 增加
print(f['aaa'])

f['aaa'] = 3  # 修改value
print(f['aaa'])

f['info']['name'] = 'Eason'
print(f['info'])

class A:
    def __init__(self):
        self.name = 'Peter'
a = A()

f['Ashome'] = {
    'list':[1,2,3,4,5],             # 可以存列表
    'dict':{'a':1,'b':2},           # 可以存字典
    'class_obj':a,                  # 可以存类的实例对象
    'time':datetime.datetime.now(), # 可以存datetime对象
    1:'aaa',                        # 数字可以当key
}
print(f['Ashome'])                  # f.close()后不能打印
f.close()
'''
生成如下:
'info', (0, 50)
'aaa', (512, 5)
'shopping', (1024, 56)
'Ashome', (1536, 196)
'''

 

####载入shelve文件

import shelve

f = shelve.open('shelve_test') # 不用加后缀名。不用管是三个文件中的哪一个

#可以直接增删改查
f['shopping'] = {
    'name':'iphoneX',
    'price':'7888'
}

data = f.get('info')
data2 = f.get('shopping')
print(data)
print(data2)

print(f['aaa'])
print('items: ',f.items())  # ItemsView(<shelve.DbfilenameShelf object at 0x0000025E46CB7630>)
f.close()
'''
生成如下:
'info', (0, 50)
'aaa', (512, 5)
'shopping', (1024, 56)
'''

 

十一、pickle模块
  1.便于存储。序列化过程将文本信息转变为二进制数据流。这样就信息就容易存储在硬盘之中,当需要读取文件的时候,从硬盘中读取数据,然后再将其反序列化便可以得到原始的数据。在Python程序运行中得到了一些字符串、列表、字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中的Pickle模块就派上用场了,它可以将对象转换为一种可以传输或存储的格式。

  2.便于传输。当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把這个对象转换为字节序列,在能在网络上传输;接收方则需要把字节序列在恢复为对象。

 

import pickle

lists = [123, "中文", [456]]
strs = "字符串"
num = 123
dic = {'a':1,'b':2}

#### 序列化操作:(变成字节字符串)
# 方式一:
f = open("pickle.txt", "wb")    # 以wb方式打开一个文件

# 写入
pickle.dump(lists, f)           # 序列化到文件
pickle.dump(strs, f)
pickle.dump(num, f)
pickle.dump(dic, f)

f.close()

# 方式二:
g = open('a.txt','wb')
g.write(pickle.dumps(lists))
g.write(pickle.dumps(strs))
g.write(pickle.dumps(num))
g.write(pickle.dumps(dic))

g.close()

#### 反序列化操作:
# 方式一:
f = open("pickle.txt", "rb+")

# 读取
data = pickle.load(f)   # 从文件反序列化
print(data)
data = pickle.load(f)
print(data)
data = pickle.load(f)
print(data)
data = pickle.load(f)
print(data)

f.close()

# 方式二:
g = open('a.txt','rb')
data = pickle.loads(g.read())
print(data)

g.close()

 

 

十二、json模块

 

import json

dic={'name':'alvin','age':23,'sex':'male'}

#### 序列化
# 方式一:
d = json.dumps(dic)         # 把字典序列化

f=open('JSON_file','w')     # 打开文件
f.write(d)                  # 写入文件
f.close()

# 方式二:
f=open('JSON_file','w')
json.dump(dic,f)
f.close()


#### 反序列化
# 方式一:
f=open('JSON_file')
data=json.loads(f.read())
print(data)
f.close()

# 方式二:
f=open('JSON_file')
data=json.load(f)
print(data)
f.close()

 

十三、shutil模块
  shutil.copyfileobj(f1,f2,length):拷贝文件,需自行打开文件
  shutil.copyfile(f1,f2):拷贝文件,传入文件名即可,无需打开文件
  shutil.copymode(f1,f2):仅拷贝权限,内容,组,用户不变
  shutil.copystat(f1,f2):拷贝状态的信息
  shutil.copy(f1,f2):拷贝文件和权限
  shutil.copy2(f1,f2):拷贝文件和状态信息
  shutil.copytree(f1,f2):拷贝目录和文件
  shutil.rmtree(f):删除目录和文件
  shutil.move(f1,f2):移动目录和文件

  shutil.make_archive():压缩包
  base_name:压缩包文件名或压缩包路径,文件名时保存到当前目录,否则保存到制定路径
  format:压缩包类型zip(既打包又压缩),tar(只打包不压缩),bztar,gztar
   root_dir:要压缩的文件夹路径
  owner:用户
  group:组
  logger:用于记录日志,通常是logging.Logger对象

十四、zipfile模块:
  用以压缩,解压某文件
   压缩:
    z = zipfile.Zipfile('f1.zip','w')
      z.write(要压缩的文件)
      z.close()
  解压:
    z = zipfile.Zipfile('f1.zip','r')
    z.extractall()
    z.close()

十五、tarfile模块
  压缩:
    tar = tarfile.open('f1.tar','w')
    tar.add(要压缩的文件路径,arcname=文件名)
    tar.close()
  解压:
    tar = tarfile.open(f1.tar,'r')
    tar.extractall()
    tar.close()

 

 

十六、hmac模块
速度较快


import hmac

h = hmac.new(
    "天王盖地虎".encode(encoding='utf-8'),
    "你是二百五".encode(encoding='utf-8')
)

print(h.digest())       # b'R\x90\xf7\xd9o\x88tPa\x02\x13\xe0\xf2u<\x80'
print(h.hexdigest())    # 5290f7d96f887450610213e0f2753c80

 

十七、re模块
元字符:. ^ $ * + ? {} [] | () \
*:匹配任意次任意一个字符
+:匹配1到无穷多次任意一个字符
?:匹配0到1次任意一个字符

{3}:匹配3次任意一个字符
{1,4}:匹配1到4次任意一个字符
{1,}:匹配1到无穷多次任意一个字符

字符集:取消元字符特殊功能,除了\,^,-
[cd]:字符集,匹配c或d任意一个字符
[a-z]:匹配a到z任意一个字符
[w*]:匹配w或*
[^t,v]:取反,取除了t和v以外的字符

\d:[0-9]
\D:[^0-9]
\s:[\t\n\r\f\v]
\S:[^\t\n\r\f\v]
\w:[a-zA-Z0-9]
\W:[^a-zA-Z0-9]
\b:匹配单词跟任意特殊字符间的位置,例:re.findall(r'I\b','hello,I an a LI$T')

方法:
1. re.findall():所有结果都返回到一个列表里
2. re.search():函数将对整个字符串进行搜索,并返回第一个匹配的字符串的match对象。
3. re.match(): 总是从字符串“开头”去匹配,并返回匹配的字符串的match对象。所以当我用re.match()函数去匹配字符串非开头部分的字符串时,会返回NONE。
4. re.split():
5. re.sub():等同于replace
6. re.compile()
7. re.subn():高阶版sub
8. re.finditer():把匹配到的元素变成一个迭代器对象
9. .groupdict():返回一个字典

import re

####findall
ret = re.findall('w\w{3}','hello world')    # 以w开头的3个[a-zA-Z0-9]字符
ret2 = re.findall('w..l','hello world')

print('ret:',ret)       # ['worl']
print('ret2:',ret2)     # ['worl']

####match
str1 = 'Hello World!'
print(re.match(r'e', str1))     # None

####search
ret3 = re.search('sb','fhjahsdfsb')
print('ret3:',ret3)     # <_sre.SRE_Match object; span=(8, 10), match='sb'>
print('ret3:',ret3.group())     # sb

ret4 = re.search('sb','fhjahsdfsb').group()
print('ret4:',ret4)

####()命名分组
ret5 = re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/oab')
#其实就是匹配'\d{3}/\w{3}',“?P<id>”是特殊命名格式,把id的值对应为123,name对应oab
print(ret5.group())
print('--------')
print(ret5.group(2))
print('--------')
print(ret5.group('id'))
print(ret5.group('name'))

####split
ret6 = re.split('[j,s]','1sdjksal')     #根据j和s分割,先按j分,再按s分,返回一个列表
ret7 = re.split('[j,s]','sdjksal')      #第一个元素是空,如果[]内的字符是匹配的第一个,返回''

print('ret6:',ret6)     # ['1', 'd', 'k', 'al']
print('ret7:',ret7)     # ['', 'd', 'k', 'al']


####sub
ret8 = re.sub('a..x','sb','hfjasalexxdhf',1)  # 最后的参数表示替换次数
print('ret8:',ret8)     # hfjassbxdhf(alex已被替换成sb)

####compile
obj = re.compile('\.com')   # 把匹配规则转换成obj对象,可多次在不同的字符串中调用
ret9 = obj.findall('jfakjdfka.comfadf')
print('ret9:',ret9)         # ['.com']

####补充
ret = re.findall('www.(?:\w+).com','www.baidu.com') # 括号内写?:代表匹配全部,不加仅匹配括号内内容
print(ret)      # ['www.baidu.com']
ret = re.findall('www.(\w+).com','www.baidu.com')
print(ret)      # ['baidu']

####subn
ret = re.subn('\d','abc','hfkajhdsf23dfja') # 替换进阶版,返回一个元祖,第二个元素是共匹配次数
print(ret)      # ('hfkajhdsfabcabcdfja', 2)

####finditer
ret = re.finditer('\d','as3sydfsj478jfkds') # 返回迭代器对象
print(ret)      # <callable_iterator object at 0x000001681C1091D0>
print(next(ret).group())    # 3
print(next(ret))    # <_sre.SRE_Match object; span=(9, 10), match='4'>
print(next(ret).group())    # 7

####\b:匹配单词跟任意特殊字符间的位置
print(re.findall(r'I\b','hello,I am a LI$T'))   # ['I', 'I']
正则re
import re

s = 'chen321ronghua123'

res = re.match('^chen\d+',s)
print(res)          # <_sre.SRE_Match object; span=(0, 7), match='chen321'>
print(res.group())  # chen321

res = re.search('r.+a',s)
print(res.group())      # ronghua

res = re.search('r[a-z]+a',s)
print(res.group())      # ronghua

# 返回字典
res = re.search("(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)","abcd1234daf@34")
print(res.groupdict())      # {'id': '1234', 'name': 'daf'}

res = re.search("(?P<id>[0-9]+)(?P<name>[a-zA-Z]+)","abcd1234daf@34").group('id')
print(res)      # 1234

a = re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
print(a)    # {'province': '3714', 'city': '81', 'birthday': '1993'}

# 分割
a = re.split('[0-9]+','abc12de3f4a5gh')
print(a)    # ['abc', 'de', 'f', 'a', 'gh']

a = re.split('[0-9]','abc12de3f4a5gh')
print(a)    # ['abc', '', 'de', 'f', 'a', 'gh']

# 替换
a = re.sub("[0-9]+","|","abc12d3f45gh",count=2)
print(a)    # abc|d|f45gh
正则2

flags = re.I:忽略大小写
flags = re.M:改变^和$的行为
flags = re.S:匹配任意字符包括换行

 

十八、验证码

import random

def ran(num=4):     # 参数代表几位验证码
    check_code = ''
    list1 = [chr(i) for i in range(65,91)]      # 选出大写字母
    list2 = [j for j in range(0,10)]            # 0-9以内的数字
    list3 = [chr(k) for k in range(97,123)]     # 选出小写字母
    # print(list2)

    for i in range(0,num):
        choice1 = random.randint(1,3)
        # print(choice1)
        if choice1 == 1:
            check_code += str(random.choice(list1))
        elif choice1 == 2:
            check_code += str(random.choice(list2))
        else:
            check_code += str(random.choice(list3))

    print(check_code)

ran()
# print(chr(122))
自实现简陋版
import random

def code():
    c = ''
    for i in range(4):
        add = random.choice([random.randrange(10),chr(random.randrange(65,91))])
        # 生成一个列表,第一个元素是0-9以内的数字,第二个元素对应ASCII表里的大写字母,再从二者之间随机挑一个
        print('add:',add)
        c += str(add)
    print(c)

code()
高级版