• 17Python学习之常用内置模块


    常用内置模块

    os 模块

    os的文件操作

    remove()

    remove是删除文件的命令,需要一个参数,如果传入的是一个路径,报 IsADirectoryError 错误

    语法:

    remove(file_path)

    例1:

    import os
    
    os.remove('/tmp/a.txt')
    

    rename()

    rename既能修改文件名,也能修改目录名,需要两个参数,第一个是原文件名,第二个是目标文件名。 修改文件名不会改变文件中的内容。

    语法:

    rename(src, dst)

    注意:

    如果目标文件名存在:

    在Linux系统中,会直接覆盖。报 OSError (目标文件存在时) 或 FileExistsError (源文件不存在时)错误

    例1:

    # 创建文件和目录
    mkdir -p /tmp/dir1/dir2		# 创建目录
    touch /tmp/dir1/a.txt		# 创建文件
    echo "This is a test file in old_file named a.txt" >> /tmp/dir1/a.txt	# 向文件写入内容
    

    结果是:

    /tmp
    └── dir1
    ├── a.txt
    └── dir2

    import os
    
    os.rename('/tmp/dir1', '/tmp/dir')             # 给目录改名
    os.rename('/tmp/dir/a.txt', '/tmp/dir/test.txt')    # 在改名后的目录中修改文件名
    

    运行结果:

    /tmp
    └── dir
    ├── dir2
    └── test.txt

    rmdir()

    rmdir是删除目录,如果目录不为空,将报 OSError (非空报错)或 FileNotFoundError (不存在报错)错误

    语法:

    rmdir(path)

    例1:

    创建目录

    mkdir /tmp/dir1				# 创建目录
    touch /tmp/dir1/a.txt		# 目录中创建文件,使目录不为空
    tree						# tree查看结果,返回树状结构
    

    /tmp
    └── dir1
    └── a.txt

    import os
    
    os.rmdir('/tmp/dir1')
    

    运行结果:

    Traceback (most recent call last):
    File "/projects/oldboy/laptop/day09/test_file.py", line 6, in
    os.rmdir('/tmp/dir1')
    OSError: [Errno 39] Directory not empty: '/tmp/dir1'

    removedirs()

    removedirs也是删除目录,跟rmdir的区别是,如果层级目录都是空,removedirs会逐层删除空目录。

    语法:

    removedirs(path)

    例1:

    # 创建目录结构
    mkdir -p /tmp/dir1/dir2/dir3/dir4
    touch /tmp/dir1/dir2/a.txt
    tree									# 用tree查看结果
    

    结果如下:

    /tmp

    └── dir1
    └── dir2
    ├── a.txt
    └── dir3
    └── dir4

    import os
    
    os.removedirs('/tmp/dir1/dir2/dir3/dir4')
    

    运行结果:

    └── dir1
    └── dir2
    └── a.txt

    说明:

    由于dir4删除后dir3也是一个空目录,removedirs会继续删除空目录,直到dir2,里面有个a.txt目录不为空,如果dir2也是空,会继续删除下去。而rmdir只会删除dir4,这是removedirs和rmdir最明显的区别

    rmtree()

    上面两个删除目录的方法,无法删除非空目录。rmtree方法可以删除非空目录,这个方法位于 shutil 模块中,要使用该方法需要先导入模块

    语法:

    rmtree(path)

    例1:

    mkdir -p /tmp/dir1/dir2/dir3/dir4
    touch /tmp/dir1/dir2/dir3/dir4/a.txt
    tree									# 用tree查看结果
    

    运行结果:

    /tmp/
    └── dir1
    └── dir2
    └── dir3
    └── dir4
    └── a.txt

    import os
    import shutil
    
    # os.rmdir('/tmp/dir1/dir2')			# 报错:OSError
    shutil.rmtree('/tmp/dir1/dir2')			# 正常删除
    

    运行结果:

    /tmp/
    └── dir1

    os的路径操作

    os的路径操作在子模块中,即os.path模块中

    dirname()

    dirname返回传入的path中的路径名,并不会验证路径和文件是否存在

    例1:

    import os
    
    ret = os.path.dirname('/tmp/dir1/dir2/a.txt')
    print(ret)
    

    运行结果:

    /tmp/dir1/dir2

    basename()

    basename 返回给定路径中的文件名,同dirname一样,也不会考虑文件或路径是否存在,只管返回文件名,如果路径以斜线结尾,那么将返回空

    例1:

    import os
    
    ret = os.path.basename('/tmp/dir1/dir2/a.txt')
    print(ret)
    

    运行结果:

    a.txt

    split()

    split 以元组的形式返回路径名和文件名,不考虑路径是否有效

    例1:

    import os
    
    ret = os.path.split('/tmp/dir1/dir2/a.txt')
    print(ret)
    

    运行结果:

    ('/tmp/dir1/dir2', 'a.txt')

    splittext()

    splittext 同split一样也是返回一个元组,区别在于,splittext 返回的元组中以英文的句号为分隔,相当于返回的是文件的后缀名。句点搜索从右往左,如果没有返回空

    例1:

    import os
    
    my_path = '/tmp/dir1/dir2/a.txt'
    ret = os.path.split(my_path)
    print('split返回:', ret)
    
    ret1 = os.path.splitext(my_path)
    print('splitext返回', ret1)
    

    运行结果:

    split返回: ('/tmp/dir1/dir2', 'a.txt')
    splitext返回 ('/tmp/dir1/dir2/a', '.txt') # 返回的相当于是后缀名

    isdir()

    isdir判断给出的路径是不是目录,只有路径真实存在并且是目录的时候才返回True,否则都是False,如果是软连接,该软连接指向的也是目录,返回的结果也是True

    例1:

    mkdir /tmp/dir1					# 创建目录
    touch /tmp/dir1/a.txt			# 创建文件
    ln -s /tmp/dir1 /test			# 创建软连接
    
    import os
    
    mypath = '/tmp/dir1/a.txt'			# 不是目录是一个文件的路径
    ret = os.path.isdir(mypath)
    print(ret)
    
    mypath2 = '/test'
    ret2 = os.path.isdir(mypath2)
    print(ret2)
    

    运行结果:

    Fasle

    True

    isfile()

    判断给出的路径是不是一个文件

    判断给出的路径是不是一个软连接

    exists()

    判断一个文件或目录是否存在,存在返回True,否则返回False

    import os
    
    mypath = '/tmp/dir1/a.txt'
    ret = os.path.exists(mypath)
    print(ret)
    

    运行结果:

    True

    sys 模块

    argv()

    argv是一个列表,该列表存储的是从命令行指向代码时传入的参数, 第一个参数默认是文件名。

    例1:

    import sys
    
    for idx, value in enumerate(sys.argv):
        print(f'第 { idx } 个参数是:{value}')
    

    运行方式:

    python3 /projects/sysdemo.py  你好 数学 英语
    

    运行结果:

    第 0 个参数是:/projects/sysdemo.py
    第 1 个参数是:你好
    第 2 个参数是:数学
    第 3 个参数是:英语

    exit()

    exit 是一个退出函数,他有一个参数 status 指明是按照什么状态退出的,默认是None 他跟 0 是一个意思,说明是正常退出的,status的取值范围是 0 - 127,这个退出状态在Linux中表现为 echo $? 显示的状态码,有时候可以帮助我们查找异常退出的情况

    例1:

    import sys
    
    try:
        num = int(input('请输入一个整数:'))
    except ValueError:
        # 我们定义数据转换异常就抛出错误代码为 15
        sys.exit(15)
    

    运行方式:

    python3 /projects/sysdemo.py
    请输入一个整数: a					# 提示我们输入整数,但我们输入了一个字母
    echo $?							# $? 打印出退出码
    

    运行结果:

    15

    getwindowsversion()

    获取Windows系统的版本信息, 仅支持在Windows系统上运行 ,他的返回值是一个列表

    例1:

    import sys
    
    print(sys.getwindowsversion())			
    

    path()

    path是Python解释器的查找路径,他是一个列表,Python解释器会在列表中的目录下去查找相应的模块信息,如果我们有自定义的模块路径,可以通过append加入该列表

    例1:

    import sys
    
    print(sys.path)
    

    paltform属性

    这是一个属性,不是方法,我们可以通过他获取当前程序运行的平台,然后我们可以针对不同的平台运行对应的程序

    对应平台如下:

    平台 对应代码
    AIX 'aix'
    Linux 'linux'
    Windows 'win32'
    Windows/Cygwin 'cygwin'
    macOS 'darwin'

    例1:

    import sys
    
    ret = sys.platform
    if ret.startswith('linux'):
        print('这是Linux平台')
    elif ret.startswith('win32'):
        print('这是Windows平台')
    

    在Linux下运行的结果:

    这是Linux平台

    在Windows下运行的结果:

    这是Windows平台

    time 模块

    time提供了与时间相关的一些函数

    time模块常用的方法有:

    time()

    time()返回从 1970-01-01 00:00:00 秒到当前时间经过的秒数

    例1:

    import time
    
    ret = time.time()
    print(ret)
    

    运行结果:

    1596771508.143643

    gmtime()

    该方法有一个参数,输入相应的描述,会给出具体的时间对象

    gmtime() 返回格林尼治时间,该方法返回的是一个time类型的结构化时间对象,我们可以使用下标或者属性名将值取出来

    下标 属性名 说 明 值范围
    0 tm_year 年份 2020
    1 tm_mon 月份 1-12
    2 tm_mday 1-31
    3 tm_hour 0-23
    4 tm_min 0-59
    5 tm_sec 0-61,因为涉及到闰秒,可查看文档
    6 tm_wday 星期几 0-6,周一是0
    7 tm_yday 一年中的第几天 0-366
    8 tm_isdst 夏令时 0,1或-1,夏令时为1, 否则为0,-1表示未知
    无索引 tm_zone 时区名缩写 /
    无索引 tm_gmtoff 以秒为单位向UTC东时区偏移 /

    例1:

    import time
    
    ret = time.gmtime()
    print(ret)
    print(type(ret))
    print('年份是:', ret[0])           # 下标方式取年份
    print('月份是:', ret.tm_mon)       # 属性方式取月份
    

    运行结果:

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=7, tm_hour=3, tm_min=51, tm_sec=24, tm_wday=4, tm_yday=220, tm_isdst=0)
    <class 'time.struct_time'>
    年份是: 2020
    月份是: 8

    例2:

    import time
    
    ret = time.gmtime(1297879384)
    print(ret)
    print(f'给定的秒数是:{ret.tm_year} 年 {ret.tm_mon} 月 {ret.tm_mday} 日 '
          f'{ret.tm_hour}:{ret.tm_min}:{ret.tm_sec} 星期{ret.tm_wday + 1}')
    

    运行结果:

    time.struct_time(tm_year=2011, tm_mon=2, tm_mday=16, tm_hour=18, tm_min=3, tm_sec=4, tm_wday=2, tm_yday=47, tm_isdst=0)
    给定的秒数是:2011年 2 月 16 日 18:3:4 星期3

    localtime()

    该方法有一个参数,输入相应的描述,会给出具体的时间对象

    获取本地时间,用法跟gmtime()一样,只是 用的是本地时区

    import time
    
    ret = time.localtime()		# 中国是东八区,用gmtime() hour 需要加8,localtime不需要
    print(ret)
    print(type(ret))
    print('年份是:', ret[0])           # 下标方式取年份
    print('月份是:', ret.tm_mon)       # 属性方式取月份
    

    运行结果:

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=7, tm_hour=12, tm_min=10, tm_sec=26, tm_wday=4, tm_yday=220, tm_isdst=0)
    <class 'time.struct_time'>
    年份是: 2020
    月份是: 8

    strftime()

    strftime()是格式化时间戳,将时间戳转换成易读的格式

    语法:

    strftime(格式 [, 时间对象])

    注意:

    时间对象可选,如果时间对象没有,默认是 localtime() 获取的时间戳

    占位符 说明
    %a 当前地区的星期缩写
    %A 当前地区的星期全称
    %b 当前地区月份的缩写
    %B 当前地区月份的全称
    %p 12小时制,大写方式显示上午(AM),下午(PM)
    %U 显示当前为一年中的第几周,以星期天为每周的第一天
    %W 显示当前为一年中的第几周,以星期一为每周的第一天
    %w 以数字的形式显示,星期中的第几天(0-6,星期天是0)
    %y 年:两位数的方式表示年份
    %Y 年:完整的四位数表示年份
    %m 月:以两位数显示
    %d 日:以两位数显示
    %H 时:24小时制,以两位数显示
    %I 时:12小时制,以两位数显示
    %M 分:以两位数显示
    %S 秒:以两位数显示
    %z 显示当前的时区(东八区:+0800)
    %% 显示一个百分号,转义

    例1:

    import time
    
    ret = time.strftime('%Y-%m-%d %H:%M:%S')
    print(ret)
    

    运行结果:

    2020-08-07 13:49:21

    strptime()

    将易读的时间,解析成时间对象,时间字符串和格式化的格式必须完全一致,否则会报 ValueError 错误

    语法:

    strptime(时间字符串, 格式)

    例1:

    import time
    
    time_str = '2020-08-07 14:52:32'
    # time_str = '2020/08/07 14:52:32'			报错,因为年月日的分隔符不匹配
    ret = time.strptime(time_str, '%Y-%m-%d %H:%M:%S')	# 格式必须跟time_str中的格式和分隔符一样
    print(ret)
    

    运行结果:

    time.struct_time(tm_year=2020, tm_mon=8, tm_mday=7, tm_hour=14, tm_min=52, tm_sec=32, tm_wday=4, tm_yday=220, tm_isdst=-1)

    datetime模块

    date类

    date类中是日期相关的内容,date类只处理年月日

    该类需要三个初始化参数 year, month, day

    语法:

    datetime.date(year, month, day)

    说明:

    三个参数的取值范围如下,如果有一个超出了范围,报 ValueError 错误

    1 <= year <= 9999
    1 <= month <=12
    1<= day <= 给定月份在年份中的天数
    

    例1:

    import datetime
    
    ret = datetime.date(2020, 8, 7)
    print(ret)
    

    运行结果:

    2020-08-07

    常用函数:

    方法 说明
    方法
    today() 获取当前日期
    fromtimestamp(timestamp) 将时间戳转换成日期
    fromordinal(days) 返回给定天数是从1年1月1日经过days天的日期,它和 toordinal 函数正好相反
    toordinal() 将一个日期转换成从1年1月1日开始的天数,它和 fromordinal 函数正好相反
    fromisoformat(date_string) 将一个给定的字符串格式的日期,转换成日期对象,字符串格式必须是:YYYY-mm-dd, 3.7版本及以上才支持
    fromisocalendar(year, week, day) 给一个日历的,年,周和天,返回该位置的日期, 周[1-53],天[1-7], 3.8版本及以上才支持
    属性
    year 获取date对象中的年
    month 获取date对象中的月
    day 获取date对象中的日
    resolution 跟datedelta计算的最小单位即:days=1

    例2:

    import datetime
    
    print('today方法:', datetime.date.today())
    print('fromtimestamp方法:', datetime.date.fromtimestamp(1596788844))
    print('toordinal方法:', datetime.date.toordinal(datetime.date.today()))
    print('fromordinal方法:', datetime.date.fromordinal(737644))
    
    ret = datetime.date.today()
    print('当前年份是:', ret.year)
    print('当前月份是:', ret.month)
    print('当前日期是:', ret.day)
    

    运行结果:

    today方法: 2020-08-07
    fromtimestamp方法: 2020-08-07
    toordinal方法: 737644
    fromordinal方法: 2020-08-07
    当前年份是: 2020
    当前月份是: 8
    当前日期是: 7

    time类

    time类中是时间,time类中只处理:时、分、秒、微秒、毫秒和时区

    语法:

    datetim.time(hour, minute, microsecond, tzinfo=None)

    说明:

    参数的取值范围如下,如果超出了范围,报 ValueError 错误

    0 <= hour <= 24
    0 <= minute< 60
    0 <= minute< 60
    0 <= microsecond < 1000000
    

    常用函数:

    方法 说明
    isoformat(timespec='auto') 指定显示的最小单位:
    默认是auto,精确到微秒;
    hours,精确到小时;
    minutes,精确到分钟;
    seconds,精确到秒
    strftime(format_string) 按给定的格式输出时间

    例1:

    from datetime import time
    
    ret = time(17, 27, 18, 200)
    print('时间对象:', ret)
    print('时:', ret.hour)
    print('分:', ret.minute)
    print('秒:', ret.second)
    print('微秒:', ret.microsecond)
    print('不指定单位:', ret.isoformat())                       # 不指定默认是auto,精确到为秒
    print('指定最小单位为时:', ret.isoformat(timespec='hours'))  # 指定显示最小单位为小时
    print('指定显示最小单位为分:', ret.isoformat(timespec='minutes'))  # 指定显示最小单位为分钟
    print('指定显示最小单位为秒:', ret.isoformat(timespec='seconds'))  # 指定显示最小单位为秒
    print(ret.strftime('%H 时 %M 分 %S 秒'))
    

    运行结果:

    时间对象: 17:27:18.000200
    时: 17
    分: 27
    秒: 18
    微秒: 200
    不指定单位: 17:27:18.000200
    指定最小单位为时: 17
    指定显示最小单位为分: 17:27
    指定显示最小单位为秒: 17:27:18
    17 时 27 分 18 秒

    datetime类

    datetime类中是日期和时间,相当于整合了date和time

    语法:

    datetime(year, month, day, hour, minute, second, microsecond)

    说明:

    参数的取值范围如下:

    MINYEAR <= year <= MAXYEAR,
    1 <= month <= 12,
    1 <= day <= number of days in the given month and year,
    0 <= hour < 24,
    0 <= minute < 60,
    0 <= second < 60,
    0 <= microsecond < 1000000,
    

    常用函数:

    方法 说明
    today() 获取当前时间包含时区tzinfo
    now() 获取当前时间不包含时区
    fromtimestamp() 将时间戳转换成日期
    timestamp() 将日期转换成时间戳
    strftime() 格式化日期
    strptime() 解析日期
    date() 获取日期
    time() 获取时间

    例1:

    from datetime import datetime
    
    print('获取时间', datetime.today())
    print('获取时间:', datetime.now())
    print('将时间戳转换成日期:', datetime.fromtimestamp(1596788844))
    print('将日期转换成时间戳:', datetime.now().timestamp())
    print('格式化日期:', datetime.now().strftime('%Y年 %m月 %d日  %H时 %M分 %S秒'))
    print('日期解析:', datetime.strptime('2020年 08月 07日  18时 09分 56秒', '%Y年 %m月 %d日  %H时 %M分 %S秒'))
    print('获取日期:', datetime.today().date())
    print('获取时间:', datetime.today().time().isoformat(timespec='seconds'))
    print('返回日期和时间的字符串:', datetime.today().isoformat(sep=' ', timespec='seconds'))
    

    运行结果:

    获取时间 2020-08-07 18:10:43.937599
    获取时间: 2020-08-07 18:10:43.937662
    将时间戳转换成日期: 2020-08-07 16:27:24
    将日期转换成时间戳: 1596795043.93768
    格式化日期: 2020年 08月 07日 18时 10分 43秒
    日期解析: 2020-08-07 18:09:56
    获取日期: 2020-08-07
    获取时间: 18:10:43
    返回日期和时间的字符串: 2020-08-07 18:10:43

    timedelta类

    timedelta类是一个时间变化量,可以跟一个日期和日期时间对象进行数学计算,从而获得需要的新时间

    注意:

    timedelta只能和date、datetime、timedelta进行数学计算, 不能和time进行计算

    语法:

    timedelta(weeks, days, hours, minutes, seconds, microsecons, milliseconds)

    说明:

    0 <= microseconds < 1000000
    0 <= seconds < 3600*24 (the number of seconds in one day)
    -999999999 <= days <= 999999999
    

    支持的操作有(详见官方文档):

    +、-、*、/、//、%、divmod

    例1:

    import datetime
    
    mydate = datetime.date.today()      # 获取当前日期
    delta1 = datetime.timedelta(days=10) # 初始化 timedelta
    print('加之前:', mydate)
    mydate += delta1
    print('加之后:', mydate)
    
    mydatetime = datetime.datetime.now()
    delta2 = datetime.timedelta(hours=2, minutes=10) # 初始化 timedelta
    print('加之前:', mydatetime)
    mydatetime += delta2     # 加10天零8小时10分钟
    print('加之前:', mydatetime)
    
    delta3 = delta1 + delta2
    print('delta相加:', delta3)
    
    mytime = datetime.datetime.now().time()
    # mytime += delta2          # 报错,不支持这样的操作
    print('时间是:', mytime)
    

    运行结果:

    加之前: 2020-08-07
    加之后: 2020-08-17
    加之前: 2020-08-07 18:28:54.503255
    加之前: 2020-08-07 20:38:54.503255
    delta相加: 10 days, 2:10:00
    时间是: 18:28:54.503284

    random模块

    此模块提供了和随机数相关的方法(random是伪随机数)。在模块内部,使用了将方法赋值给了属性的方式,比如:randrange 是一个属性,在模块内部定义了将Random类的方法赋值给了randrange,因此randrange实际指向的是randrange方法。

    randrange内部实现如下:

    _inst = Random()
    randrange = _inst.randrange
    

    random模块常用方法有:

    random.random()

    获取 [0.0, 1.0) 之间的浮点数

    例1:

    import random
    
    print(random.random())
    

    运行结果:

    0.25784570611056934

    random.randint(a, b)

    返回一个在 [a, b] 之间的整数N, 包含a 或 b

    例1:

    import random
    
    print(random.randint(1, 5))
    

    运行结果:

    3

    random.uniform(a, b)

    返回一个 [a,b]或[a,b) 之间的浮点数(a,b大小顺序不限)

    例1:

    import random
    
    print(random.uniform(10, 5))
    

    运行结果:

    6.314250748038026

    random.shuffle()

    将一个有序的可变数据类型,打乱,无返回值,改变的是可迭代对象本身

    例1:

    import random
    
    li = list(range(10))
    print(li)
    random.shuffle(li)
    print(li)
    

    运行结果:

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    [2, 8, 3, 5, 1, 7, 6, 9, 0, 4]

    random.smaple(iter, x)

    从一个可哈希的序列或集合中,返回长度为x的一个列表,如果x的长度大于序列或集合,会报 ValueError 错误。如果序列中的元素有重复,那么返回的列表中元素也可能会重复

    例1:

    import random
    
    li = list(range(10))
    print(li)
    ret = random.sample(li, 5)
    print(ret)
    

    运行结果:

    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    [3, 0, 7, 8, 5]

    例2:

    import random
    
    li = [1, 2, 3, 4, 5, 6, 7, 2, 1, 5, 7]			# 元素重复
    print(li)
    ret = random.sample(li, 5)
    print(ret)
    

    运行结果:

    [1, 2, 3, 4, 5, 6, 7, 2, 1, 5, 7]
    [2, 4, 3, 1, 2] # 2 重复获得

    random.randrange()

    返回一个指定范围内的随机数,randrange有三个参数,start和step可以省略,start指定随机数的开始,stop指定随机数的结束位置,step指定步长

    例1:

    import random
    
    ret = random.randrange(1, 101, 2)			# 返回奇数的随机数
    print('1~100之间的奇数随机数:', ret)
    

    运行结果:

    3

    json模块和pickle模块

    json模块

    json是JavaScript Object Notation的缩写,即java脚本兑换标记语言,已经成为一种简单的数据交换格式,在Python中,只有集合(set)不能用json表示

    序列化:将内存中的结构化数据,转换成字节传,用以保存在文件或者通过网络传输称为线性化过程

    反序列化: 从文件或网络中获取的数据,转换成内存中原来的数据类型称为返序列化过程

    json将数据转换成字符串,用于存储或网络传输,由于并未转换成字节串,所以不太彻底

    dumps()

    dumps是将内存中的结构化数据进行序列号,即将结构化数据转换成字符串,dumps是从内存到内存,而dump是从内存到文件

    例1:

    import json
    
    li = [1, 2, 3, 4]
    ret = json.dumps(li)        # dumps将结构化数据转换成字符串
    print(type(ret))
    print('%r' % ret)           # 用原始格式显示
    
    tu = (1, 2, 3, 4)
    ret = json.dumps(tu)        # 元组转换后变成了列表的格式,圆括号变成了方括号
    print(type(ret))
    print('%r' % ret)           # 用原始格式显示
    

    运行结果:

    <class 'str'>
    '[1, 2, 3, 4]'

    <class 'str'>
    '[1, 2, 3, 4]'

    loads()

    loads是将从文件或网络中获取的数据,转化为结构化数据,即反序列化。loads是从内存到内存,load是从文件到内存

    import json
    
    li = [1, 2, 3, 4]
    ret = json.dumps(li)        # ret是序列化后的字符串
    print('dumps的结果是:%r, 类型是:%s' % (ret, type(ret)))
    res = json.loads(ret)       # 进行反序列号
    print('loads的结果是:%r, 类型是:%s' % (res, type(res)))
    

    运行结果:

    dumps的结果是:'[1, 2, 3, 4]', 类型是:<class 'str'>
    loads的结果是:[1, 2, 3, 4], 类型是:<class 'list'>

    dump 和load

    dump和load的作用域上面dumps和loads一样,区别在于,dump和load是转换成流,写入文件和从文件中读取json。 dump和load都一次性存储和读取,如果需要多次,直接用文件的write和read模式

    例1:

    import json
    
    li = [1, 2, 3, 4]
    with open('ret.txt', mode='a+', encoding='utf-8') as f:
        json.dump(li, f)
    
    # 读取
    with open('ret.txt', mode='r', encoding='utf-8') as f:
        ret = json.load(f)
        print(ret)
    

    运行结果:

    [1, 2, 3, 4]

    例2:

    import json
    
    li = [1, 2, 3, 4]
    with open('ret.txt', mode='a+', encoding='utf-8') as f:
        f.write(json.dumps(li) + '
    ')		# 利用write和dumps
    
    # 读取
    with open('ret.txt', mode='r', encoding='utf-8') as f:
        for i in f.readlines():
            ret = json.loads(i.strip())		# 利用read和loads
            print(ret)
    

    运行结果:

    [1, 2, 3, 4]
    [1, 2, 3, 4]

    pickle模块

    pickle的用法跟json一样,有四个方法dump、dumps、load、loads,它能处理Python中的所有数据类型包括集合set,

    将Python中所有的数据类型转换成 字节串 ,序列化过程

    将字节串转换成Python中数据类型,反序列化过程。

    json和pickle 的区别:

    1. pickle所有类型都可以序列化,结果是字节串
    2. pickle的dump和load自带多次写和多次读。
    3. pickle不能跨语言,只能针对Python语言。
    4. dumps前是什么类型,loads后还是什么类型,类型不变

    例1:

    import pickle
    
    li = [1, 2, 3, 4]
    ret1 = pickle.dumps(li)  # 转换成pickle字节串
    print('dumps后的类型是:', type(ret1))
    print('dumps后的结果是:', ret1)
    
    tu = (1, 2, 3, 4)
    ret2 = pickle.dumps(tu)  # 转换成pickle字节串
    print('dumps后的类型是:', type(ret2))
    print('dumps后的结果是:', ret2)
    
    se = {1, 2, 3, 4}
    ret3 = pickle.dumps(se)  # 转换成pickle字节串
    print('dumps后的类型是:', type(ret3))
    print('dumps后的结果是:', ret3)
    
    # 反序列化
    res1 = pickle.loads(ret1)
    res2 = pickle.loads(ret2)
    res3 = pickle.loads(ret3)
    print('loads后的结果是:', res1)
    print('loads后的结果是:', res2)
    print('loads后的结果是:', res3)
    

    运行结果:

    dumps后的类型是: <class 'bytes'>
    dumps后的结果是: b'x80x03]qx00(Kx01Kx02Kx03Kx04e.'
    dumps后的类型是: <class 'bytes'>
    dumps后的结果是: b'x80x03(Kx01Kx02Kx03Kx04tqx00.'
    dumps后的类型是: <class 'bytes'>
    dumps后的结果是: b'x80x03cbuiltins set qx00]qx01(Kx01Kx02Kx03Kx04ex85qx02Rqx03.'
    loads后的结果是: [1, 2, 3, 4]
    loads后的结果是: (1, 2, 3, 4)
    loads后的结果是: {1, 2, 3, 4}

    例2:

    import pickle
    
    with open('ret.txt', mode='wb') as f:
        se = {1, 2, 3, 4}
        tu = (1, 2, 3, 4)
        li = [1, 2, 3, 4]
        dic = {'1': 1, '2': 2, '3': 3, '4': 4}
        pickle.dump(se, f)
        pickle.dump(tu, f)
        pickle.dump(li, f)
        pickle.dump(dic, f)
    
    
    with open('ret.txt', mode='rb') as r:
        res1 = pickle.load(r)
        res2 = pickle.load(r)
        res3 = pickle.load(r)
        res4 = pickle.load(r)
        print(res1)
        print(res2)
        print(res3)
        print(res4)
    

    运行结果:

    {1, 2, 3, 4}
    (1, 2, 3, 4)
    [1, 2, 3, 4]
    {'1': 1, '2': 2, '3': 3, '4': 4}

    hashlib模块

    hashlib封装了一些用于加密的类,如:md5, sha1, sha512,可用 print(dir(hashlib)) 查看所有加密方法

    加密的目的:用于判断和验证,而并非解密

    特点:

    1. 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的
    2. 单向加密,不可逆
    3. 原始数据的一点小的变化,将导致结果的差异非常大

    加密分为三个步骤:

    1. 获取加密对象
    2. 调用加密对象的update方法,进行加密
    3. 通过hexdigest方法获取加密结果

    不管用那种加密方式,都是上面三个步骤

    例1:

    import hashlib
    
    # 获取一个md5加密对象
    md5_object = hashlib.md5()
    # 调用update方法进行加密,参数必须是bytes类型
    md5_object.update('md5加密'.encode())
    # 利用hexdigest获取加密结果
    ret = md5_object.hexdigest()
    print('md5加密结果是:', ret)
    

    运行结果:

    md5加密结果是: a3c9c2fe682a79e3b1703f001ba245a9

    例2:

    import hashlib
    
    # 分块加密
    md5_object = hashlib.md5()
    md5_object.update('我爱'.encode())
    md5_object.update('我的祖国'.encode())
    ret = md5_object.hexdigest()
    print('分块加密结果是:', ret)
    
    # 未分块加密
    md5_object2 = hashlib.md5()
    md5_object2.update('我爱我的祖国'.encode())
    ret2 = md5_object2.hexdigest()
    print('未分块加密结果是:', ret2)
    

    运行结果:

    分块加密结果是: e83482ae91900eadbc2384fc92ac6c98
    未分块加密结果是: e83482ae91900eadbc2384fc92ac6c98

    例3:

    利用加密实现注册和登录验证

    import hashlib
    
    
    # 注册将用户名和密码写入文件
    def regist(username, pwd):
        if username != '' and pwd != '':
            ret = get_encryption(username, pwd)
            with open('pwd.txt', mode='at', encoding='utf-8') as p, open('users.txt', mode='at', encoding='utf-8') as u:
                u.write(username + '
    ')
                p.write(ret + '
    ')
            return True
        else:
            return False
    
    
    # 登录从文件读取用户名和密码并校验
    def login(username, pwd):
        if username != '' and pwd != '':
            with open('pwd.txt', mode='rt', encoding='utf-8') as p, open('users.txt', mode='rt', encoding='utf-8') as u:
                # 校验用户名
                for name in u.readlines():
                    # 需要strip清除后面的换行符或空格
                    if name.strip() == username.strip():
                        # 校验密码
                        for passwd in p.readlines():
                            # 需要strip清除后面的换行符或空格再比较,因为存储的时候加了回车符号
                            if passwd.strip() == get_encryption(username.strip(), pwd.strip()):
                                return True
                # 如果用户名不对,返回False,不验证密码
                else:
                    return False
    
    
    # 获取加密密码信息,并返回加密信息
    def get_encryption(username, pwd):
        m = hashlib.md5()
        m.update(username.encode())
        m.update(pwd.encode())
        return m.hexdigest()
    
    
    while 1:
        op = input("请选择操作(1-注册   2-登录   0-退出) :")
        if op == '0':
            break
        elif op == '1':
            username = input('请输入用户名:')
            password = input('请输入密  码:')
            if regist(username, password):
                print('注册成功')
            else:
                print('用户名密码不能为空!')
        elif op == '2':
            username = input('请输入用户名:')
            password = input('请输入密  码:')
            if login(username, password):
                print('登录成功')
            else:
                print('登录失败')
        else:
            print('输入错误,请重新输入!!!')
    
    

    collections模块

    这个模块提供了抽象基类,可以用来创建一个特定的接口

    Counter类

    Counter类是dict的一个子类,它的参数是一个可哈希的对象或者一个映射,并返回一个字典,字典的键是可哈希对象的每个元素,值是该键的数量。还有一个most_common() 方法可以获取返回值的前n个

    例1:

    import collections
    
    ret = collections.Counter('this is a test')
    print(ret)
    print(ret.most_common(3))					# 获取前三个值
    ret2 = collections.Counter(cats=3, dogs=4)
    print(ret2)
    

    运行结果:

    Counter({'t': 3, 's': 3, ' ': 3, 'i': 2, 'h': 1, 'a': 1, 'e': 1}) # 键是字符串中的字符,值是字符的个数统计

    [('t', 3), ('s', 3), (' ', 3)]

    Counter({'dogs': 4, 'cats': 3})

    namedtuple类

    namedtuple类是元组的子类,命名元组对于为csv或sqlite3模块返回的结果元组分配字段名称特别有用

    语法:

    conllections.namedtuple('说明', [变量1, 变量2])

    说明:

    1. 说明 必须没有空格,可以带下划线
    2. 变量必须是字符串

    例1:

    import collections
    
    Point = collections.namedtuple('说明', ['x', 'y'])
    p = Point(12, 23)
    ret = p.x + p.y
    print(ret)
    

    运行结果:

    35

    defaultdict类

    defaultdict是字典dict的一个子类,用法跟字典类似,参数是一个default_factory

    语法:

    collections.defaultdict([default_factory[, ...]])

    例1:

    s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
    d = collections.defaultdict(list)
    for k, v in s:
        d[k].append(v)
    
    ret = d.items()
    print(ret)
    print(dict(ret))
    

    运行结果:

    dict_items([('yellow', [1, 3]), ('blue', [2, 4]), ('red', [1])])
    {'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}

  • 相关阅读:
    C# Access2003操作辅助类(AccessHelper.cs)
    校园网综合管理系统(一)
    使用Devexpress开发简单进销存系统(1)数据库的建立
    软件测试(一):测试基础和缺陷管理
    异步多线程
    服务器下载文件到本地,更新服务器文件
    WCF深入浅出学习1
    利用Oracle 发送邮件(utl_smtp)
    多线程之 ThreadStart 和 ParameterizedThreadStart 委托
    javascript实现的google日历,beehive.calendar.js v0.1
  • 原文地址:https://www.cnblogs.com/zcf-blog/p/13475229.html
Copyright © 2020-2023  润新知