4.5 python相关模块(自定义模块/random/time/datetime/os/sys/json/pickle/hashlib/collections模块) 学习笔记

1 自定义模块

1)__name__属性的使用

  • 模块以脚本方式运行时,__name__是固定的字符串: __main__

  • 模块以导入方式运行时,__name__就是本模块的名字

  • if __name__ == "__main__": pass

    • 可以在模块导入时不执行在判断语句中出现的代码(函数执行打印之类的测试语句)

2)系统导入模块的路径问题

  • 内存中:如果之前导入成功过的模块,直接使用已经存在的模块

  • 内置路径中:安装目录/Lib(site-package目录下都是自己下载安装的第三方包)

  • PYTHONPATH:import时寻找模块的路径

  • sys.path: 是一个可修改的路径列表

    # 将自建模块的路径添加到sys.path中 
    import sys
    sys.path.append('路径')
    
    # 将自建模块的相对路径添加到sys.path中
    import sys
    import os
    sys.path.append(os.path.dirname(__file__) + '相对路径')  # __file__ 当前脚本路径  os.path.dirname() 目标路径父路径 + 父路径下的新建模块路径
    
  • 如果上述路径都找不到,就报错

3)导入模块的多种方式:

  • import xxx:导入一个模块的所有成员
  • import aaa,bbb:一次性导入多个模块的成员。不推荐这种写法,分开写。
  • from xxx import a:从某个模块中导入指定的成员。
  • from xxx import a,b,c:从某个模块中导入多个成员。
  • from xxx import *:从模块中导入所有成员。

4)from xxx import * 控制成员被导入

默认情况下,所有的成员都会被导入。

__all__是一个列表,用于表示本模块可以被外界使用的成员。元素是成员名的字符串。

注意:

__all__只是对from xxx import *这种导入方式生效。其余的方式都不生效。

5)相对导入

  • 针对某个项目中的不同模块之间进行导入,称为相对导入

  • 只有一种格式:from 相对路径 import xxx

  • 相对路径:包含了点号的一个相对路径。

    • . 表示的是当前的路径。
    • …表示的是父路径。
    • …表示的是父路径的父路径。
# 相对导入同项目下的模块
# from ..z import zz            # 容易向外界暴露zz模块
from ..z.zz import *
# 不使用相对导入的方式,导入本项目中的模块
# 通过当前文件的路径找到z的路径
import os
import sys
sys.path.append(os.path.dirname(os.path.dirname(__file__)) + '/z')
from zz import *

2 random模块

此模块提供了和随机数获取相关的方法

  • random.random():获取[0.0,1.0)范围内的浮点数
  • random.randint(a, b):获取[a, b]范围内的一个整数
  • random.uniform(a, b):获取[a, b)范围内的浮点数
  • random.shuffle(x):把参数指定的数据中的元素打乱。参数必须是一个可变的数据类型。
  • random.sample(x, k):从x中随机抽取k个数据返回一个列表

3 time模块

封装了获取时间戳和字符串形式的时间的一些方法。

1)获取时间戳

  • 时间戳:从时间元年(1970 1 1 00:00:00)到现在经过的秒数
  • 获取:time.time() 返回当前时间

2)获取格式化时间对象

  • time.gmtime() # 打印GMT:格林威治时间–欧洲时间
  • time.localtime() # 打印当地时间
  • 参数
    • 默认参数是当前系统时间的时间戳
    • 自己设置参数,time.gmtime(1) # 时间元年过一秒后对应的时间对象
print(time.gmtime())
print(time.localtime())
'''
返回值:
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=3, tm_hour=11, tm_min=14, tm_sec=33, tm_wday=4, tm_yday=94, tm_isdst=0)
time.struct_time(tm_year=2020, tm_mon=4, tm_mday=3, tm_hour=19, tm_min=14, tm_sec=33, tm_wday=4, tm_yday=94, tm_isdst=0)
注:欧洲人每周开始是星期0
'''
print(time.gmtime(1))  # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
  • 时间对象 --> 时间戳

    • time.mktime(时间对象)

    • t1 = time.localtime()  # 时间对象
      t2 = time.mktime(t1)  # 获取对应的时间戳
      print(t2)
      

3)格式化时间对象和字符串之间的转换

  • 时间对象 --> 字符串

    • time.strftime(‘格式’)

    • s = time.strftime('year:%Y %m %d %H:%M:%S')
      print(s)  # year:2020 04 03 20:09:50
      
  • 字符串 --> 时间对象

    • time.strptime(‘字符串’, ‘格式’)

    • times = time.strptime('2010 10 10', '%Y %m %d')
      print(times)  # time.struct_time(tm_year=2010, tm_mon=10, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=6, tm_yday=283, tm_isdst=-1)
      

4)time模块的三大对象

  • 格式化时间对象:time.struct_time
  • 时间戳
  • 时间字符串
  • 三大对象之间的关系:
    在这里插入图片描述

5)暂停当前进程,睡眠

  • time.sleep(秒数)

  • for i in range(5):
        print(time.strftime('%Y %m %d %H:%M:%S'))
        time.sleep(1)  # 休眠一秒钟
    '''
    2020 04 03 20:24:23
    2020 04 03 20:24:24
    2020 04 03 20:24:25
    2020 04 03 20:24:26
    2020 04 03 20:24:27
    '''
    

4 datetime 日期时间模块

封装了一些和日期时间相关的类

1)date类

  • datetime.date(年, 月, 日)

  • 获取date对象的各个属性。.year .month .day

    import datetime
    d = datetime.date(2010,10,10)
    print(d)
    print(d.year)
    print(d.month)
    print(d.day)
    '''
    2010-10-10
    2010
    10
    10
    '''
    

2)time类

  • datetime.time(时, 分, 秒)

  • time类的属性。.hour .minute .second

    t = datetime.time(10,48,59)
    print(t)
    print(t.hour)
    print(t.minute)
    print(t.second)
    '''
    10:48:59
    10
    48
    59
    '''
    

3)datetime类

  • datetime.datetime(年, 月, 日, 时, 分, 秒)

  • datetime类的属性。.year .month .day .hour .minute .second

    dt = datetime.datetime(2010,11,11,11,11,11)
    print(dt)
    '''
    2010-11-11 11:11:11
    '''
    
  • datetime中的类,主要是用于数学计算的.

4)timedelta类

  • timedelta:时间的变化量

  • datetime.timedelta(days=1)

    td = datetime.timedelta(days=1)
    print(td)  # 1 day, 0:00:00
    
  • 参与数学运算,只能和以下三类进行数学运算: date,datetime,timedelta

td = datetime.timedelta(days=1)
d = datetime.date(2010,10,10)
res = d - td
print(res) # 2010-10-09
  • 时间变化量的计算会产生进位

    t = datetime.datetime(2010,10,10,10,10,00)
    td = datetime.timedelta(seconds=3)
    res = t - td
    print(res)  # 2010-10-10 10:09:57
    
  • 和时间段进行运算的结果类型:和另一个操作数保持一致

    d = datetime.date(2010,10,10)
    d = datetime.datetime(2010,10,10,10,10,10)
    d = datetime.timedelta(seconds=20)
    td = datetime.timedelta(days=1)
    res = d + td
    print(type(res))
    # 2010-10-10 10:09:57
    # <class 'datetime.timedelta'>
    
  • 练习

    # 练习:计算某一年的二月份有多少天.
    # 普通算法:根据年份计算是否是闰年.是:29天,否:28
    # 用datetime模块.
    # 首先创建出指定年份的3月1号.然后让它往前走一天.
    year = int(input("输入年份:"))  # 2020
    # 创建指定年份的date对象
    d = datetime.date(year,3,1)
    # 创建一天 的时间段
    td = datetime.timedelta(days=1)
    res = d - td
    print(res.day)  # 29  2月29天  2020是闰年
    

5 os模块

和操作系统相关的一些操作被封装到这个模块中

1)和文件操作相关

  • 重命名

    • os.rename(原文件名, 改的文件名)

      import os
      os.rename('a.txt','b.txt')
      
  • 删除

    • 删除文件 os.remove(‘文件名’)

      os.remove('a.txt')
      
    • 删除空目录 os.removedirs(目录名)

      os.removedirs('aa')
      
    • 删除带内容目录:使用shutil模块删除

      import shutil
      shutil.rmtree('aa')
      

2)和路径相关操作

  • 被封装到另一个子模块中:os.path

  • 获取父目录

    res = os.path.dirname(r'd:/aaa/bbb/ccc/a.txt') # 不判断路径是否存在,去掉文件名返回此文件的目录,若参数为相对路径,则输出空字符串
    print(res)
    
  • 获取文件名

    res = os.path.basename(r'd:/aaa/bbb/ccc/a.txt')
    print(res)
    
  • 把路径中的路径名和文件名切分开,结果是元组.

    res = os.path.split(r'd:/aaa/bbb/ccc/a.txt')
    print(res)
    
  • 拼接路径

    path = os.path.join('d:\\','aaa','bbb','ccc','a.txt')
    print(path)
    
  • 转换绝对路径

    • 如果是/开头的路径,默认是在当前盘符下

      res = os.path.abspath(r'/a/b/c')
      
    • 如果不是以/开头,默认当前路径

      res = os.path.abspath(r'a/b/c')
      
  • 判断

    • 绝对路径

      print(os.path.isabs('a.txt'))
      
    • 目录

      print(os.path.isdir('d:/aaaa.txt')) # 文件不存在.False
      
    • 文件是否存在

      print(os.path.exists('d:/a.txt'))
      
    • 是否文件

      print(os.path.isfile('d:/asssss.txt'))      # 文件不存在.False
      

6 sys 模块

  • 和python解释器相关的操作

  • 获取命令行方式运行的脚本后面的参数

    import sys
    print("脚本名:",sys.argv[0])      # 脚本名
    print("第一个参数:",sys.argv[1])      # 第一个参数
    print("第二个参数:",sys.argv[2])      # 第二个参数
    # print(type(sys.argv[1]))        # str
    # 应用
    # arg1 = int(sys.argv[1])
    # arg2 = int(sys.argv[2])
    # print(arg1 + arg2)
    
  • 解释器寻找模块的路径

    sys.path('')
    
  • 返回已经加载的模块

    print(sys.modules)
    

7 json模块

1)序列化

  • 把内存中的数据,转换成字节或字符串的形式,以便于进行存储或者网络传输.

  • 内存中的数据(结构化数据)
    在这里插入图片描述

  • 磁盘上的数据(线性数据)
    在这里插入图片描述

  • 序列化和反序列化的区别:

    • 序列化:内存中数据 -> 字节串/字符串
    • 反序列化:字节串/字符串 -> 内存中的数据 : 反序列化
      在这里插入图片描述

2)json

  • json是不完整的序列化:json将数据转换为字符串,用于存储或网络传输
  • json.dumps(数据) # 将数据序列化为json字符串
import json
s = json.dumps([1,2,3]) # 把指定的对象转换成json格式的字符串
print(type(s))
print(s)        # '[1,2,3]'   [1,2,3]

s = json.dumps((1,2,3))     # 元组序列化后,变成列表
print(s)

res = json.dumps(10)
print(res)          # '10'

res = json.dumps({'name':'Andy','age':10})
print(res)          # '{"name": "Andy", "age": 10}'

res = json.dumps(set('abc'))      # Object of type 'set' is not JSON serializable
  • json.dump(json, 文件) # 将序列化的json结果写入到文件中

    with open('a.txt',mode='at',encoding='utf-8') as f:
        json.dump([1,2,3],f)
    
  • json.loads() # 将json字符串反序列化为数据

    # 反序列化
    res = json.dumps([1,2,3])
    lst = json.loads(res)           # 反序列化
    print(type(lst))
    print(lst)
    
    # 元组会变成列表
    # res = json.dumps((1,2,3))
    # lst = json.loads(res)           # 反序列化
    # print(type(lst))
    # print(lst)
    
  • json.load() # 将json字符串从文件中反序列化

    with open('a.txt',encoding='utf-8')as f:
        res = json.load(f)
        print(type(res))
        print(res)
    
  • json文件通常是一次性写、一次性读。使用另一种方式,可以实现多次写、多次读。

    # 把需要序列化的对象.通过多次序列化的方式, 用文件的write方法,把多次序列化后的json字符串
    # 写到文件中.
    with open('json.txt',mode='at',encoding='utf-8') as f:
        f.write(json.dumps([1,2,3]) + '\n')
        f.write(json.dumps([4,5,5]) + '\n')
    
    #  把分次序列化的json字符串,反序列化回来
    with open('json.txt',mode='rt',encoding='utf-8') as f:
        # res = json.loads(f.readline().strip())
        # print(res)
        # res2 = json.loads(f.readline().strip())
        # print(res2)
        # 使用循环改进:
        for x in f:
            print(json.loads(x.strip()))
    

8 pickle模块

1)序列化

  • 序列化过程:将Python中所有的数据类型.转换成字节串
  • 反序列化过程:将字节串转换成python中数据类型

2)序列化和反序列化方法

  • pickle.dumps() pickle.loads() # 所有python的数据类型都可以进行序列化和反序列化

    bys = pickle.dumps(set('abc'))
    res = pickle.loads(bys)
    print(type(res))
    
  • pickle.dump() # 把pickle序列化内容写入文件中

with open('c.txt',mode='wb') as f:
    pickle.dump([1,2,3],f)
  • pickle.load() # 从文件中反序列化pickle数据

    with open('c.txt',mode='rb') as f:
        res = pickle.load(f)
        print(type(res))
        print(res)
    
  • 多次pickle序列化数据到同一个文件中

    with open('c.txt',mode='ab') as f:
        pickle.dump([1,2,3],f)
        pickle.dump([1,2,3],f)
        pickle.dump([1,2,3],f)
    
  • 多次pickle从文件中反序列化数据

    with open('c.txt',mode='rb') as f:
        for x in range(4):
            res = pickle.load(f)
            print(res)
    
  • pickle常用场景:和json一样,一次性写入,一次性读取.

3)json和pickle的比较

  • json
    • 不是所有的数据类型都可以序列化.结果是字符串.
    • 不能多次对同一个文件序列化.
    • json数据可以跨语言
  • pickle
    • 所有python类型都能序列化,结果是字节串.
    • 可以多次对同一个文件序列化
    • 不能跨语言.

9 hashlib 模块

1)封装一些用于加密的类

2)加密目的

用于判断和验证,而并非解密

3)特点

  • 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的.

    m = hashlib.md5()
    m.update(b'abc')
    m.update(b'def')
    print(m.hexdigest())
    
    n = hashlib.md5()
    n.update(b'abcdef')
    print(m.hexdigest())  # 与上面加密结果相同
    
  • 单向加密,不可逆.

  • 原始数据的一点小的变化,将导致结果的非常大的差异,'雪崩’效应.

4)数据加密

  • 数据加密三大步骤

    • 获取一个加密对象
    • 使用加密对象的update,进行加密,update方法可以调用多次
    • 通常通过hexdigest获取加密结果(字符串),或digest()方法(二进制).
    import hashlib
    # 获取加密对象
    m = hashlib.md5()
    # 使用加密对象的update,进行加密
    m.update('abc加密'.encode('utf-8'))  # .encode()进行转码
    # 通过hexdigest获取加密结果
    res = m.digest()
    res = m.hexdigest()
    print(res)
    
  • 加密用途

    验证:用另一个数据加密的结果和第一次加密的结果对比.

    如果结果相同,说明原文相同.如果不相同,说明原文不同.

  • 不同加密算法区别

    不同加密算法实际上就是加密结果的长度不同.

    s = hashlib.sha224()  # 56位16进制,相当于224位二进制
    s.update(b'abc')
    print(len(s.hexdigest()))
    
    print(len(hashlib.md5().hexdigest()))  # 32位16进制,相当于128位二进制
    print(len(hashlib.sha256().hexdigest()))  # 64位16进制,相当于256位二进制
    
  • 在创建加密对象时,可以指定参数,称为salt.不使用update()

    # 指定参数
    m = hashlib.md5(b'abc')
    print(m.hexdigest())
    # 通过update()设置参数
    m = hashlib.md5()
    m.update(b'abc')
    print(m.hexdigest())
    

5)实例

# 注册,登录程序:

def get_md5(username,passwd):
    m = hashlib.md5(username[::-1].encode('utf-8'))
    m.update(username.encode('utf-8'))
    m.update(passwd.encode('utf-8'))
    return m.hexdigest()


def register(username,passwd):
    # 加密
    res = get_md5(username,passwd)
    # 写入文件
    with open('login',mode='at',encoding='utf-8') as f:
        f.write(res)
        f.write('\n')

    # username:xxxxxx

def login(username,passwd):
    # 获取当前登录信息的加密结果
    res = get_md5(username, passwd)
    # 读文件,和其中的数据进行对比
    with open('login',mode='rt',encoding='utf-8') as f:
        for line in f:
            if res == line.strip():
                return True
        else:
            return False

while True:
    op = int(input("1.注册 2.登录 3.退出"))
    if op == 3 :
        break
    elif op == 1:
        username = input("输入用户名:")
        passwd = input("输入密码:")
        register(username,passwd)
    elif op == 2:
        username = input("输入用户名:")
        passwd = input("输入密码:")
        res = login(username,passwd)
        if res:
            print('登录成功')
        else:
            print('登录失败')

10 collections模块

定义了一些常用容器类

1)namedtuple() # 命名元组

  • 作用:创建一个tuple的子类,并添加属性

  • 用法:

    • 创建

    • 通过属性访问元素

    • 通过索引访问元素

      from collections import namedtuple, defaultdict, Counter
      # 创建
      Rectangle = namedtuple('Rectangle_class',['length','width'])
      #
      r = Rectangle(10,5)
      # 通过属性访问元组的元素
      print(r.length)
      print(r.width)
      
      # 通过索引的方式访问元素
      print(r[0])
      print(r[1])
      

2)defaultdict() # 默认值字典

以键值对方式创建字典,当访问的key不存在时,默认创建不存在的key=默认参数返回值

  • 默认参数:int 返回值:0

    d = defaultdict(int,name='Andy',age=10)
    print(d['name'])
    print(d['age'])
    print(d['addr'])            # {'addr':0} 也会被添加
    print(d)
    
  • 默认参数:自定义函数(不能有参数) 返回值:函数返回值

    def f():
        return 'hello'
    
    d = defaultdict(f,name='Andy',age=10)
    print(d['addr'])
    print(d)
    

3)Counter() # 计数器

c = Counter('abcdefabccccdd')
print(c)  # Counter({'c': 5, 'd': 3, 'a': 2, 'b': 2, 'e': 1, 'f': 1})
print(c.most_common(3))  # [('c', 5), ('d', 3), ('a', 2)]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值