美文网首页
19. Python之常用模块

19. Python之常用模块

作者: 随便写写咯 | 来源:发表于2021-02-03 03:21 被阅读0次

    1. time模块

    1.1 time的格式

    三种格式:
    1. 时间戳
    2. 按照某种格式显示的时间
    3. 结构化的时间
    
    时间戳: 从1970年到代码执行时间点期间经历过的秒数, 调用time.time()
    
    import time
    print(time.time())
    >> 1612284368.302347
    
    格式化显示时间: 调用time.strftime()
    
    import time
    print(time.strftime('%Y-%m-%d %H:%M:%S'))
    >> 2021-02-03 00:48:35
    
    结构化时间: 调用time.localtime()
    
    import time
    print(time.localtime()) # time.localtime()显示当前时间的具体信息
    >> time.struct_time(tm_year=2021, tm_mon=2, tm_mday=3, tm_hour=0, tm_min=52, tm_sec=34, tm_wday=2, tm_yday=34, tm_isdst=0)
    
    # 可以赋值给变量, 然后通过变量名.key去获得value
    import time
    info = time.localtime()
    print(info.tm_year)
    >> 2021
    print(info.tm_mon)
    >> 2
    

    1.2 不同格式的应用场景

    1. 时间戳: 用于时间间隔的计算
    2. 格式化显示时间: 按照某种格式展示
    3. 结构化时间: 用于单独获取当前时间的某部分的value
    

    1.3 不同格式之间的转换

    1. 结构化时间 ---time.mktime(结构化时间)---> 时间戳格式 
    
    import time
    
    print(time.localtime())
    >> time.struct_time(tm_year=2021, tm_mon=2, tm_mday=3, tm_hour=1, tm_min=19, tm_sec=47, tm_wday=2, tm_yday=34, tm_isdst=0)
    timestamp=time.localtime()
    print(time.mktime(timestamp))
    >> 1612286387.0
    
    2. 时间戳 ---time.localtime(时间戳)---> 结构化时间
    
    import time
    
    s_time = time.time()
    print(s_time)
    >> 1612286616.320777
    print(time.localtime(s_time))
    >> time.struct_time(tm_year=2021, tm_mon=2, tm_mday=3, tm_hour=1, tm_min=23, tm_sec=36, tm_wday=2, tm_yday=34, tm_isdst=0)
    
    3. 结构化时间 ---time.strftime()---> 格式化字符串时间
    
    import time
    
    l_time = time.localtime()
    print(l_time)
    >> time.struct_time(tm_year=2021, tm_mon=2, tm_mday=3, tm_hour=1, tm_min=32, tm_sec=29, tm_wday=2, tm_yday=34, tm_isdst=0)
    print(time.strftime('%Y-%m-%d %H:%M:%S',l_time))
    >> 2021-02-03 01:32:29
    
    4. 格式化字符串时间 ---time.strptime()---> 结构化时间
    
    import time
    
    f_time = time.strftime('%Y-%m-%d %H:%M:%S')
    print(f_time)
    >> 2021-02-03 01:35:04
    s_time = time.strptime(f_time, '%Y-%m-%d %H:%M:%S')
    print(s_time)
    >> time.struct_time(tm_year=2021, tm_mon=2, tm_mday=3, tm_hour=1, tm_min=35, tm_sec=4, tm_wday=2, tm_yday=34, tm_isdst=-1)
    
    注意: 格式化字符串的时间格式与时间戳不能直接转换, 需要通过结构化时间进行转换
    
    案例: 假设当前时间为'1990-07-10 10:10:10', 如果计算7天后的时间
    
    实现过程: 把格式化时间 > 转成结构化时间 > 时间戳 >  进行时间运算 >  转回时间戳 > 转回格式化时间
    
    import time
    
    f_time = '1990-07-10 10:10:10'
    
    # 第一步: 格式化字符串时间, 转成结构化时间
    s_time = time.strptime(f_time,'%Y-%m-%d %H:%M:%S')
    print(s_time)  # >> time.struct_time(tm_year=1990, tm_mon=7, tm_mday=10, tm_hour=10, tm_min=10, tm_sec=10, tm_wday=1, tm_yday=191, tm_isdst=-1)
    
    # 第二步: 结构化时间, 转成时间戳
    
    time_stamp = time.mktime(s_time)
    print(time_stamp)  # >> 647575810.0
    
    # 第三步: 时间戳+7天
    
    new_time_stamp = time_stamp + 7 * 86400
    print(new_time_stamp)  # >> 648180610.0
    
    # 第四步: 将新的时间戳, 转换成新的结构化格式
    
    new_s_time = time.localtime(new_time_stamp)
    print(new_s_time) # >> time.struct_time(tm_year=1990, tm_mon=7, tm_mday=17, tm_hour=10, tm_min=10, tm_sec=10, tm_wday=1, tm_yday=198, tm_isdst=0)
    
    # 第五步: 将新的结构化格式, 转成最终的新的格式化字符串格式
    
    new_f_time = time.strftime('%Y-%m-%d %H:%M:%S',new_s_time)
    print(new_f_time) # >> 1990-07-17 10:10:10
    
    # 结果
    # '1990-07-10 10:10:10' ---> '1990-07-17 10:10:10'
    

    1.4 time模块支持的其他格式

    import time
    
    print(time.asctime())
    >> Wed Feb  3 02:06:54 2021 
    

    2. datetime模块

    2.1 用于获取当前时间

    import datetime
    print(datetime.datetime.now())
    >> 2021-02-03 01:08:12.385710 # 注意: datatime获取时间的结果是datetime对象而不是字符串
    

    2.2 进行时间的运算(主要的作用)

    案例1: 计算5天后的时间
    
    import datetime
    print(datetime.datetime.now())
    >> 2021-02-03 01:10:46.131210
    print(datetime.datetime.now()+datetime.timedelta(days=5))  # days=5表示5天后
    >> 2021-02-08 01:10:46.131210
    
    案例2: 计算3天前的时间
    
    import datetime
    print(datetime.datetime.now())
    >> 2021-02-03 01:11:56.062510
    print(datetime.datetime.now()+datetime.timedelta(days=-3)) # days=-3表示3天前
    >> 2021-01-31 01:11:56.062510
    
    注意: datetime进行时间的运算不支持年, 没有此功能, 不过可以用days=365*3(计算3年后的时间)来代替
    

    2.3 时间戳转成格式化字符串格式

    好处: 一步到位
    缺点: 无法指定格式化的格式
    
    import datetime, time
    s_time = time.time()
    print(s_time) # >> 1612289400.193677
    print(datetime.datetime.fromtimestamp(s_time)) # >> 2021-02-03 02:10:00.193677
    

    3. random模块

    取随机值
    
    import random
    
    print(random.random()) # 0-1之内的小数, 开区间
    >> 0.4848350985621943
    
    print(random.uniform(1,3)) # m,n, 指定范围内的小数, 开区间
    >> 2.4436476444386885
    
    print(random.randint(1,3)) # 闭区间
    >> 3
    
    print(random.randrange(1,3)) # 左闭又开
    >> 2
    
    print(random.choice([1,2,[3,4],'a'])) # choice()中放一个列表, 每次会从列表中随机取出一个元素
    >> 1
    
    print(random.sample([1,2,3,[11,22]],2)) # sample()放一个列表, 每次按照后面指定的数字, 从列表中随机取出2个元素, 并且以列表格式返回, 注意, sample()必须指定随机取出值的个数
    >> [3, 2]
    
    list1 = [1,2,3,4,5]
    print(random.shuffle(list1)) # random.shuffle()会将列表顺序随机打乱, 并且会修改源列表
    print(list1)
    >> [2, 5, 3, 1, 4]
    

    案例: 生成随机验证码, 6位大写字母和数字的组合

    import random
    
    res = '' # 初始化一个空字符串
    for i in range(6): # 6为随机字符串, 所以循环6次, 每次从大写字母和数字中随机random.choice()取出来一个, 和res做拼接
        alpha = chr(random.randint(65,90)) # chr('数字'), 将对应的数字按照ASCII表的顺序转成字符串, 大写字母范围是65-90, 所以random.randint()取出一个数字, 然后转成字符串
        num = str(random.randint(0,9)) # str(), 将数字转成字符格式, 因为字符串只能和字符串拼接, 不能和数字拼接
        alnum = random.choice([alpha,num]) # 得到随机的大写字母和数字, 加入到random.choice(), 每次随机取出一个, 和res拼接
        res += alnum
    print(res)
    

    4. os模块

    4.1 os.getcwd()

    os.getcwd() --> 获取当前工作目录,即当前Python脚本工作的目录路径
    
    import os
    dir = os.getcwd()
    print(dir)
    >> C:\Users\David\PycharmProjects\pythonProject\模块
    

    4.2 os.chdir()

    os.chdir() --> 改变当前脚本工作目录;相当于shell下cd
    
    os.chdir(r"C:\Users\David\PycharmProjects\pythonProject\练习")
    print(os.getcwd())
    >> C:\Users\David\PycharmProjects\pythonProject\练习
    

    4.3 os.makedirs('dirname1/dirname2')

    os.makedirs('dirname1/dirname2') --> 生成多层递归目录, 支持绝对路径和相对路径
    

    4.4 os.curdir 和 os.pardir

    import os
    
    print(os.curdir) >> .  # 返回 '.', 表示当前工作目录
    print(os.pardir) >> ..  # 返回, '..', 表示上级工作目录
    

    4.5 os.removedirs('dir')

    os.removedirs('dirname1')   -->  若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    

    4.6 os.mkdir('dirname')

    os.mkdir('dirname')  -->   生成单级目录;相当于shell中mkdir dirname
    

    4.7 os.rmdir('dirname')

    os.rmdir('dirname')   -->  删除单级空目录,若目录不为空则无法删除,报错
    

    4.8 os.listdir('dirname')

    os.listdir('dirname')  -->   列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    
    import os
    print(os.listdir(r'C:\Users\David\PycharmProjects\pythonProject\s14\模块'))
    >> ['os模块.py', 'random模块.py', 'time模块.py', '__pycache__', '练习.py']
    
    print(os.listdir('.'))
    

    案例: 统计一个目录的大小

    1. os.listdir, 列出目标目录的子目录和文件
    2. 从上一步结果的列表, for循环取值, 每一进行判断, 取出来的是目录还是文件, 如果是文件, 直接os.path.getsize()取文件大小, 然后加到sum求和
    3. 如果是目录, 则递归执行os.listdir
    
    #! /usr/bin/python3                                                                                                                                                                 
      
    
    import os
    
    
    target=os.getcwd()
    def get_size(target):
        dir = os.listdir(target)
    
        sum_size = 0
        for item in dir:
            j = '{target}/{item}'.format(target=target,item=item)
            if os.path.isfile(j):
                res = os.path.getsize(j)
                sum_size += res
            else:
                sum_size += get_size(j)
        return sum_size
    
    info = get_size(target)
    print(info)
    
    

    4.9 os.remove()

    os.remove()  -->  删除一个文件
    

    4.10 os.rename("oldname","newname")

    os.rename("oldname","newname")  --> 重命名文件/目录
    

    4.11 os.stat('path/filename')

    os.stat('path/filename')  -->  获取文件/目录信息
    

    4.12 os.system("bash command")

    os.system("bash command") -->  运行shell命令,具体要看Python运行在什么平台
    

    4.13 os.environ

    os.environ  --> 获取系统环境变量
    结果是字典格式, 并且key和value都是字符串
    在整个程序任何地方都能获取到的变量
    
    添加变量到environ
    
    import os
    env = os.environ
    env['username']='admin'
    print(env)
    >> 'USERNAME': 'admin'
    
    用途: 程序运行中, 某个代码片段产生了一个变量, 并且希望这个变量也能被其他文件中的代码访问到, 那么就可以把这个变量加入到environ中
    比如, 一个用户登录, 那么在登录的运行文件中, 可以获取用户名字, 这时如果其他的文件也要调用这个用户名, 那么可以把用户名添加到系统环境变量里
    

    4.14 os.path.abspath(path)

    os.path.abspath(path)  --> 返回path规范化的绝对路径
    
    import os
    print(__file__)
    >> C:/Users/David/PycharmProjects/pythonProject # Pycharm显示
    print(os.path.abspath(__file__))
    >> C:\Users\David\PycharmProjects\pythonProject # Windows规范
    

    4.15 获取文件的dirname和basename

    import os
    print(os.path.dirname(r'a/b/c/d.txt')) >> a/b/c
    print(os.path.basename(r'a/b/c/d.txt')) >> d.txt
    
    os.path.split(path)
    
    import os
    print(os.path.split(r'a/b/c/d.txt'))
    >> ('a/b/c', 'd.txt') # 结果以元组形式返回
    

    4.16 目录和文件的判断

    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
    

    4.17 os.path.join(path1[, path2[, ...]])

    os.path.join(path1[, path2[, ...]])  --> 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
    
    import os
    print(os.path.join('a','b','c','d.txt'))
    >> a\b\c\d.txt
    

    4.18 os.path.normpath()

    os.path.normpath() --> 规范化路径
    
    import os
    print(os.path.normpath('a/b/c/d/../..'))
    >> a\b
    
    获取一个路径的上上级目录
    
    import os
    print(os.path.dirname(os.path.dirname('a/b/c/d'))) # Python2和Python3通用
    >> a/b
    

    4.19 pathlib模块

    Python3.5以后推出的用来处理路径的模块
    
    或者父级目录
    
    from pathlib import Path
    
    dir = Path(__file__)
    par = dir.parent.parent.parent
    print(par)
    >> C:\Users\David\PycharmProjects\pythonProject
    
    路径拼接
    
    from pathlib import Path
    
    dir1 = Path('a/b/c')
    dir2 = 'd/e.txt'
    print(dir1 / dir2)
    >> a\b\c\d\e.txt
    

    5 sys模块

    5.1 sys.argv

    在程序中接收执行程序时传入的参数, 类似Shell的位置参数
    sys.argv 表示所有参数, 包括程序文件本身, 结果为一个列表
    
    C:\Users\David\PycharmProjects\pythonProject\模块\sys模块.py
    
    import sys
    print(sys.argv)
    print(sys.argv[0])
    print(sys.argv[1])
    print(sys.argv[2])
    
    C:\Users\David\PycharmProjects\pythonProject\模块>python38 sys模块.py 1 2 3
    ['sys模块.py', '1', '2', '3']
    sys模块.py
    1
    2
    

    案例: 文件拷贝程序

    import sys
    
    src_file = sys.argv[1]
    dest_file = sys.argv[2]
    # 中间可以通过条件判断来显示输入的源文件和目标文件
    with open(r'%s'%(src_file), mode = 'bt') as read_f, \
        open(r'%s'%(dest_file), mode = 'wb') as write_f:
        for line in read_f:
            write_f.write(line)
    

    6 打印进度条功能

    进度条格式:
    1. 进度条宽度固定
    2. 随着进度增加, 百分比随之增加
    [#####                  ] %10
    [###########      ] %30
    
    原理:
    动态的进度条实际都用每一次打印的静态效果模拟出来的
    用新的进度条替换旧的进度条, 因为速度非常快, 所以肉眼是无法识别的
    [#             ]
    [##            ]
    [###           ]
    [####          ]
    
    1. 实现固定进度条
    
    print('[%-50s]'%('#')) # 50表示进度条宽度, "-"左对齐
    >> [#                                                 ]
    
    2. 实现百分号
    
    print('[%-50s] %s%%'%('#',100))
    >> [#                                                 ] 100%
    
    3. for循环, 实现每次打印一个#, 一共打印50次
    
    res = ''
    for i in range(50):
        res += '#'
        print('[%-50s]'%(res))
    >>
    [#                                                 ]
    [##                                                ]
    [###                                               ]
    ...
    
    4. 实现不换行打印
    
    res = ''
    for i in range(50):
        res += '#'
        print('[%-50s]'%(res),end='')
    >> [#                                                 ][##                                                ]... #此时, 所有的进度条都会在一行打印
    
    5. 实现每次打印时, 都在行首打印, 替换之前的打印结果
    
    res = ''
    for i in range(50):
        res += '#'
        print('\r[%-50s]'%(res),end='') # \r表示每次都在行首打印
    
    6. 添加打印时间间隔, 便于观看输出效果
    
    import time
    res = ''
    for i in range(50):
        res += '#'
        print('\r[%-50s]'%(res),end='')
        time.sleep(0.5)
    
    7. 模拟根据下载进度, 实现进度条打印
    
    import time
    recv_size = 0 # 初始化接受的数据
    total_size = 100000 # 数据总大小
    while recv_size < total_size:
        time.sleep(0.5) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        recv_size += 1024 # 模拟每次下载一个字节
        print(recv_size)
    >> # 此时执行会一次显示每次下载后的接受数据量的大小
    1024
    2048
    3072
    4096
    5120
    ...
    
    8. 通过打印进度条显示下载速度
    
    percent = recv_size / total_size # 每打印进度条之前, 计算接收到的数据占总数据的百分比
    hash_num = int(50 * percent) # 定义宽度为50, 那么最多50个#, 乘百分比得到每次接受完应该显示#的个数, 然后用int取整, 因为百分之会存在小数
    
    import time
    recv_size = 0 # 初始化接受的数据
    total_size = 100000 # 数据总大小
    while recv_size < total_size:
        time.sleep(0.01) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        recv_size += 1024 # 模拟每次下载1024个字节
    
        # 打印进度条
        percent = recv_size / total_size
        hash_num = int(50 * percent) * '#' # int()后的结果是应该打印的#的个数, 再*'#'就会得到n个#
        print('\r[%-50s]' % (hash_num), end='')
    
    9. 添加百分比显示
    
    import time
    recv_size = 0 # 初始化接受的数据
    total_size = 100000 # 数据总大小
    while recv_size < total_size:
        time.sleep(0.01) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        recv_size += 1024 # 模拟每次下载1024个字节
    
        # 打印进度条
        percent = recv_size / total_size
        hash_num = int(50 * percent) * '#'
        print('\r[%-50s] %d%%' % (hash_num,int(percent*100)), end='')
    
    10. 每次下载数量的控制
    
    如果总数量为1025, 而每次接受1024, 那么第一次下载会下载1024, recv_size变成1024, while循环条件判断后, 会进行下一次下载, 再下载1024个字节
    这样recv_size就变成了2048个字节, 那么第二次计算百分比就超过了总的数据量, 变成199%.
    因此, 需要控制每次下载的数量, 防止超出总的范围
    
    方法1: 每次计算中百分比后, 对百分之进行判断, 如果大于1, 那么强项转换成1, 这样最后一次无论接受了多少数据, 最后进度条输出的都是100%
    方法2: 每次进入while循环后, 再判断一次total_size和recv_size的差值, 如果差值小于1024, 那么recv_size就+=差值, 如果大于1024, 那么还是+=1024
    
    方法1:
    
    import time
    recv_size = 0 # 初始化接受的数据
    total_size = 1025 # 数据总大小
    while recv_size < total_size:
        time.sleep(1) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        recv_size += 1024 # 模拟每次下载1024个字节
    
        # 打印进度条
        percent = recv_size / total_size
        if percent > 1:
            percent = 1
        hash_num = int(50 * percent) * '#'
        print('\r[%-50s] %d%%' % (hash_num,int(percent*100)), end='')
    
    方法2:
    
    import time
    recv_size = 0 # 初始化接受的数据
    total_size = 1025 # 数据总大小
    while recv_size < total_size:
        time.sleep(1) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        diff_size = total_size - recv_size
        if diff_size < 1024:
            recv_size += diff_size
        else:
            recv_size += 1024 # 模拟每次下载1024个字节
    
        # 打印进度条
        percent = recv_size / total_size
        hash_num = int(50 * percent) * '#'
        print('\r[%-50s] %d%%' % (hash_num,int(percent*100)), end='')
    
    11. 将打印进度条做成功能
    
    import time
    
    def progress(percent):
        hash_num = int(50 * percent) * '#'
        print('\r[%-50s] %d%%' % (hash_num, int(percent * 100)), end='')
    
    
    recv_size = 0 # 初始化接受的数据
    total_size = 102500 # 数据总大小
    while recv_size < total_size:
        time.sleep(0.05) # 添加时间间隔, 每0.5秒下载1024字节, 类似模拟下载速度
        diff_size = total_size - recv_size
        if diff_size < 1024:
            recv_size += diff_size
        else:
            recv_size += 1024 # 模拟每次下载1024个字节
    
        # 打印进度条
        percent = recv_size / total_size
        progress(percent)
    

    7 shutil模块

    用于文件处理
    
    1. 将文件内容拷贝到另一个文件中
    import shutil
    shutil.copyfileobj(open('random模块.py', 'r'), open('random模块.bak.py', 'w'))
    
    1. 拷贝文件
    shutil.copyfile('f1.log', 'f2.log') # 目标文件会自动创建
    
    1. 只把源文件的权限拷贝给目标文件, 目标文件的内容, 属主, 属组不变
    shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
    
    1. 只把源文件的状态信息拷贝给目标文件, 包括: mode bits, atime, mtime, flags
    shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
    
    1. 拷贝文件和权限
    shutil.copy('f1.log', 'f2.log')
    
    1. 拷贝文件和状态信息
    shutil.copy2('f1.log', 'f2.log')
    
    1. 打包, 解包, 压缩, 解压缩
    将 /data/下的文件打包并压缩到当前程序文件运行的目录
    # root_dir表示要打包的路径
    import shutil
    shutil.make_archive("data.bak","gztar",root_dir="/data")
    
    解包解压缩
    
    t=tarfile.open('/tmp/data.tar','r')
    t.extractall('/opt')
    t.close()
    

    相关文章

      网友评论

          本文标题:19. Python之常用模块

          本文链接:https://www.haomeiwen.com/subject/yczutltx.html