• Python语言常见模块模板


    内容概要

    • 常见模块

      简介
      导入模块的两种句式(两种导入句式的优缺点)
      扩展知识
      模块的查找顺序
      json序列化模块
      time datetime时间模块
      random随机数模块
      sys解释器相关模块
      os操作系统模块
      re正则模块
      hashlib加密模块
      logging日志模块
      socket数据交互模块

       

    简介

    """
    python屈辱史
    python刚开始出来的时候被其他编程程序员瞧不起
    ps:太简单 写代码都是调用模块(调包侠 贬义词)
    随着业务的扩展其他程序员也需要使用python写代码
    写完之后发现python真香 贼好用(调包侠 褒义词)
    为什么python很牛逼
    python之所以牛逼就是因为支持python的模块非常的多 非常的全 非常的猛
    作为一名python程序员
    将来接收到某个业务需求的时候 不要上来就想着自己写 先看看有没有相应的模块已经实现
    """

    1.如何理解模块
    模块可以看成是一系列功能的结合体
      使用模块就相当于拥有了这结合体内的所有功能
    ps:使用模块编程就相当于站在巨人的肩膀上
    2.模块的分类
    1.内置模块
      解释器自带的 直接就可以使用的模块
          eg:
                   import time
                   time.sleep(3)
    2.自定义模块
      自己写的模块
          eg:
                注册功能 登录功能
    3.第三方模块
      别人写的模块 存在于网络上 使用之前需要提前下载
          eg:
    图形识别 图形可视化 语音识别
    3.模块的表现形式
    1.py文件(py文件也可以称之为是模块文件)
    2.含有多个py文件的文件夹(按照模块功能的不同划分不同的文件夹存储)
    3.已被编译为共享库或DLL的c或C++扩展(了解)
    4.使用C编写并链接到python解释器的内置模块(了解)

    导入模块的两种句式

    """
    补充说明
    以后真正的项目中 所有的py文件名称都是英文
    没有所谓的编号和中文
    eg:
    错误的 01.变量的使用
    正确的 test01.py
    学习模块的时候 模块文件的名称就得用英文

    py文件被当做模块导入的时候不需要考虑后缀
    """
    导入模块的句式1 import句式
    import md
       """
      import md
      执行文件是   02 模块的导入句式.py
      被导入文件是 md.py

      1.会产生执行文件的名称空间
      2.产生被导入文件的名称空间并运行该文件内所有的代码 存储名字
      3.在执行文件中会获取一个模块的名字 通过该名字点的方式就可以使用到被导入文件名称空间中的名字

      补充说明
          同一个程序反复导入相同的模块 导入语句只会执行一次
              import md   有效
              import md   无效
              import md   无效
      """
       # money = 10
       # print(md.money)
       # print(money)


       # def read1():
       #     print('我是执行文件里面的read函数')
       # md.read2()

       # money = 1000
       # md.change()
       # print(money)
       # print(md.money)

    导入模块的句式2 from...import...句式
    # from md import money # 指名道姓的导入
       # print(money) # 999
       # money = '嘿嘿嘿'
       # print(money) # 嘿嘿嘿
       # print(read1)
       # print(md.read1())

       from md import money, read1
       read1()
       """
      1.创建执行文件的名称空间
      2.创建被导入文件的名称空间
      3.执行被导入文件中的代码 将产生的名字存储到被导入文件的名称空间中
      4.在执行文件中获取到指定的名字 指向被导入文件的名称空间
      """
    两种导入句式的优缺点
    import md
    优点:通过md点的方式可以使用到模块内所有的名字 并且不会冲突
    缺点:md什么都可以点 有时候并不想让所有的名字都能被使用
    from md import money, read1
    优点:指名道姓的使用指定的名字 并且不需要加模块名前缀
    缺点:名字及其容易产生冲突(绑定关系被修改)

    扩展知识

    1.起别名
    情况1:多个模块文件名相同(多个人写)
           from md import money as md_my
           from md1 import money as md1_my
           print(md_my)
           print(md1_my)
    情况2:原有的模块文件名复杂
          import mdddddddddd as md
           
    2.导入多个名字
    import time, sys, os
    上述导入方式建议多个模块功能相似才能适应 不相似尽量分开导入
    import time
    import os
    import sys
       
    from md import money, read1, read2
    上述导入方式是推荐使用的 因为多个名字出自于一个模块文件
       
    3.全导入
    需求:需要使用模块名称空间中很多名字 并且只能使用from...import句式
    from md import *  # *表示所有
    ps:针对*号的导入还可以控制名字的数量
    在模块文件中可以使用__all__ = [字符串的名字]控制*能够获取的名字
    4.循环导入问题
    如何理解循环导入
    循环导入就是两个文件彼此导彼此
    循环导入容易出现报错现象
    使用彼此的名字可能是在没有准备好的情况下就使用了
    如何解决循环导入保存现象
    彼此在使用彼此名字之前 先准备好
     
    """循环导入将来尽量避免出现!!! 如果真的避免不了 就想办法让所有的名字在使用之前提前准备好"""
    5.判断文件类型
    学习完模块之后 以后我们的程序运行起来可能涉及到的文件就不止一个

    所有的py文件中都自带一个__name__内置名
    当py文件是执行文件的时候 __name__的结果是__main__
    当py文件是被导入文件的时候 __name__的结果是模块名(文件名)
       
    __name__主要用于开发模块的作者测试自己的代码使用
    if __name__ == '__main__':
      当文件是执行文件的时候才会执行if的子代码
           
    上述判断一般只出现整个程序的启动文件中
           
    ps:在pycharm中可以直接编写main按tab键自动补全

    模块的查找顺序

    """
    1.先去内存中查找
    2.再去内置中查找
    3.再去sys.path中查找(程序系统环境变量) 下面详细的讲解
    """
    1.导入一个文件 然后在导入过程中删除该文件 发现还可以使用
    import md
       import time

       time.sleep(15)
       print(md.money)
    2.创建一个跟内置模块名相同的文件名
    # import time
       # print(time.time())
       from time import name
       print(name)
    ps:创建模块文件的时候尽量不要与内置模块名冲突
    3.导入模块的时候一定要知道谁是执行文件
    所有的路径都是参照执行文件来的
    import sys
       sys.path.append(r'D:\pythonProject\day22\xxx')
       import mdd
       print(mdd.name)
    """
    1.通用的方式
    sys.path.append(目标文件所在的路径)
    2.利用from...import句式
    起始位置一定是执行文件所在的路径
    from xxx import mdd
    """

    json序列化模块

    import json
    序列化: 通过某种方式把数据结构或对象写入到磁盘文件中或通过网络传到其他节点的过程。
    反序列化:把磁盘中对象或者把网络节点中传输的数据恢复为python的数据对象的过程。

    +-------------------+---------------+
       | Python            | JSON          |
       +===================+===============+
       | dict              | object        |
       +-------------------+---------------+
       | list, tuple       | array         |
       +-------------------+---------------+
       | str               | string        |
       +-------------------+---------------+
       | int, float        | number        |
       +-------------------+---------------+
       | True              | true          |
       +-------------------+---------------+
       | False             | false         |
       +-------------------+---------------+
       | None              | null          |
       +-------------------+---------------+


    #序列化
    import json

    a1 = {'name':'huchangxi','age':23,'love':'Python'}
    b1 = json.dumps(a1) #将Python字典转换成JSON字符串
    print(type(b1))
    with open('json.txt','w') as f:
       f.write(b1)  # 等价于json.dump(dic,f)

    #反序列化
    with open('json.txt','r') as f:
       c1 = f.read() # 等价于json.dump(dic,f)
       d1 = json.loads(c1) # 反序列化成为python的字典,等价于data=json.load(f)
       print(d1)

    time datetime时间模块

    import time
    #1.sleep睡觉
    #time.sleep(10) #睡10秒
    ==========================
    #2.打印当前时间戳
    #print(time.time()) #当前时间戳 1648824553.3693929
    #“1970-1-1 0:0:0” 时间戳(0)
    ==========================
    #3.计算命令1和命令2执行时间差
    print("ok")
    a1 = time.time()
    time.sleep(3)
    print("ok")
    a2 = time.time()
    print(a2 -a1) #3.008237838745117
    ==========================
    #4.时间格式
    import datetime
    #四类:date time datetime timedelta

    第一类#date
    (1).构建一个日期对象
    dt = datetime.date(2000,6,14)
    print(dt.year) #打印年份
    print(dt.month) #打印月份
    print(dt.day) #打印日期
    print(dt) #2000-06-14
    ==========================
    (2).自定义日期时间分割符
    dt1 = datetime.date(2000,6,14)
    ret = dt1.strftime("%Y/%m/%d") #自定义日期时间分割符为/(默认为“-”)
    print(ret) #2000/06/14

    (3).构建当前时间对象
    td = datetime.date.today() #2022-04-01
    print(td)
    =========================

    第二类#time
    不常用【略】
    =========================

    第三类#datetime
    (1).构建一个日期对象
    dt = datetime.datetime(2012,11,10,9,8,7)
    print(dt.year) #打印年份
    print(dt.month) #打印月份
    print(dt.day) #打印日期
    print(dt.hour) #打印小时
    print(dt.minute) #打印分钟
    print(dt.second) #打印秒
    print(dt) #2012-11-10 09:08:07
    ==========================

    (2).自定义日期时间分割符
    ret1 = dt.strftime("%Y/%m/%d %H-%M-%S")
    ret2 = dt.strftime("%Y/%m/%d %X")
    print(ret1) #2012/11/10 09-08-07
    print(ret2) #2012/11/10 09:08:07
    ==========================

    (3).构建当前时间对象
    now = datetime.datetime.now()
    print(now) #2022-04-01 23:39:31.622284
    ==========================

    (4).日期比较
    dt = datetime.datetime(2012,11,10,9,8,7)
    now = datetime.datetime.now()
    print (now > dt) #True
    ==========================

    第四类#timedelta
    (1).打印之前或未来的日期
    td = datetime.timedelta(days=3)
    print(type(td)) #<class 'datetime.timedelta'>
    print(now - td) #2022-03-29 23:44:32.204968(打印3天前的日期)
    print(now + td) #2022-04-04 23:44:32.204968(打印3天后的日期)
    print((now).weekday()+1) #5(打印今天是星期几)
    print((now + td).weekday()+1) #1(打印3天后是星期几)
    ==========================

    random随机数模块

    import random
    #1.随机数输出
    print(random.random())  # 0-1随机浮点数
    print(random.randint(1, 3))  # 范围整型随机一个(1,2,3)
    print(random.randrange(1, 3))  # 范围整型随机一个(1,2)
    print(random.choice(["a", "b", "c"]))  # 多个元素选一个
    print(random.sample(["a", "b", "c"], 2))  # 多个元素选多个
    =============================
    #2.将列表里的数据随机排序输出
    l = [1, 2, 3, 4, 5, 6]
    random.shuffle(l)
    print(l) #随机排序输出
    =============================
    #3.构建5位验证码
    print(ord("a")) #97
    print(ord("b")) #98
    print(ord("z")) #122
    print(chr(97))  # a
    print(chr(122))  # z

    def get_random_str():
       ret = []
       for i in range(5):
           random_num = str(random.randint(0, 9))
           random_lower = chr(random.randint(97, 122))
           random_upper = chr(random.randint(65, 90))
           random_char = random.choice([random_num, random_upper, random_lower])
           ret.append(random_char)

       #print(ret) #列表输出['4', '1', '6', 'a', 'Y']
       print("".join(ret))  #字符串输出416aY

       return "".join(ret)

    get_random_str()
    =============================

    sys解释器相关模块

    import sys

    #1.返回操作系统平台名称
    print(sys.platform)

    if sys.platform == "win32":
        print("win32")
    else:
       print("NO-win32")
    ============================
    #2.强制程序退出
    sys.exit() # 强制程序退出
    ============================
    #3.导入包的路径列表
    sys.path : 导入包的路径列表
    ============================
    #4.sys.argv # 命令行参数List,第一个元素是程序本身路径
    #(1)
    sys.argv
    print("请登录")
    name = input("用户名:")
    pwd = input("密码:")

    if name == "huchangxi" and pwd == "123456":
        print("登录成功")
    ============================
    #(2)
    sys.argv
    print("sys.argv:", sys.argv)
    user_index = sys.argv.index("-u") + 1
    user = sys.argv[user_index]
    pwd_index = sys.argv.index("-p") + 1
    pwd = sys.argv[pwd_index]
    if user == "huchangxi" and pwd == "123456":
        print("登录成功")
    ============================

    os操作系统模块

    import os
    #1.常用操作
    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下为"\t\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的大小
    =============================
    #2.练习1
    import os
    print(__file__) #文本的相对路径
    print(os.path.abspath(__file__)) #文本的绝对路径
    print(os.path.abspath("data.json"))  # 返回path规范化的绝对路径
    a = os.path.abspath(__file__)
    ret = os.path.split(a)
    print(ret)  # ('D:\\BaiduNetdiskDownload\\DevOPS自动化专家\\day04\\代码', 'os模块.py')
    print(os.path.basename(a)) #文件名称
    print(os.path.dirname(os.path.dirname(a))) #文件的路径
    =============================
    #3.练习1
    import os
    a = os.path.abspath(__file__)
    path = os.path.join(os.path.dirname(a),"new","data.txt")
    print("path:",path) #path: D:\BaiduNetdiskDownload\DevOPS自动化专家\day04\代码\new\data.txt
    with open(path) as f:
       print(f.read()) #hello huchangxi 回path的内容

    print(os.path.getsize(path)) #10 返回path的大小
    =========================

    re正则模块

    就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

    (1)元字符
    . :除换行符以外的任意符号,re.S模式也可以使 . 匹配包括换行在内的所有字符

    ^:匹配字符串的开头

    $:匹配字符串的末尾。

    *:匹配0个或多个的表达式。默认贪婪模式

    +:匹配1个或多个的表达式。默认贪婪模式

    ?:匹配0个或1个由前面的正则表达式,默认非贪婪模式

    { n,m}:匹配 n m 次由前面的正则表达式定义的片段,贪婪方式

    [ ]:字符集,多个字符选其一,[^...]取反

    |:匹配做正则表达式或右边正则表达式

    ( ):G匹配括号内的表达式,也表示一个组

    \:转移符
    ======================================
    import re

    # (1) . ^ $
    ret = re.findall("hello world","hello world")
    print(ret)

    ret = re.findall("^hello world$","hello python,hello world,hello re")
    print(ret)

    ret = re.findall("^hello .....$","hello world")
    print(ret)

    # (2) * + ?
    ret = re.findall("^hello .*","hello ")
    ret = re.findall("^hello .+","hello ")
    ret = re.findall("^hello .?","hello abc")

    # (3) {} ()
    ret = re.findall("hello .{5}","hello python,hello world,hello re,hello yuan")
    print(ret)
    ret = re.findall("hello .{2,5}","hello python,hello world,hello re")
    print(ret)
    ret = re.findall("hello .{5},","hello python,hello world,hello re")
    print(ret)
    ret = re.findall("hello (.*?),","hello python,hello world,hello re,hello yuan,")
    print(ret)
    # ret = re.findall("hello (.*?)(?:,|$)","hello python,hello world,hello re,hello yuan")
    # print(ret)

    # (4) [] |
    ret = re.findall("a[bcd]e","abeabaeacdeace")
    print(ret)
    ret = re.findall("[a-z]","123a45bcd678")
    print(ret)
    ret = re.findall("[^a-z]","123a45bcd678")
    print(ret)
    ret = re.findall("www\.([a-z]+)\.(?:com|cn)","www.baidu.com,www.jd.com")
    print(ret)

    # (5) \
    '''
    1、反斜杠后边跟元字符去除特殊功能,比如\.
    2、反斜杠后边跟普通字符实现特殊功能,比如\d

      \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 匹配一个特殊字符边界,比如空格 ,&,#等
    '''

    ret = re.findall("\d+","123a45bcd678")
    print(ret)
    ret = re.findall("(?:\d+)|(?:[a-z]+)","123a45bcd678")
    print(ret)
    ===================================
    (2)正则方法
    import re

    # 查找所有符合条件的对象
    # re.findall() # 返回列表
    # 查找第一个符合条件的匹配对象
    s = re.search("\d+","a45bcd678")
    print(s)
    print(s.group())

    # match同search,不过只在字符串开始处进行匹配
    s = re.match("\d+","a45bcd678")
    # print(s)
    # print(s.group())

    # 正则分割split
    ret = re.split('[ab]', 'abcd')
    print(ret)
    # 正则替换
    def func(match):

       name = match.group()
       print("name",name)
       return "xxx"

    # \1代指第一个组匹配的内容 \2第二个组匹配的内容,思考如何能将所有的名字转大写替换
    ret = re.sub("(hello )(.*?)(,)","\\1yuan\\3","hello python,hello world,hello re,")
    print("ccc",ret)

    # 编译再执行
    obj=re.compile('\d{3}')
    ret=obj.search('abc123ee45ff')
    print(ret.group()) # 123
    ========================================
    import re

    # 正则表达式:针对字符串做模糊匹配
    s = "hello yuan"
    print(s.find("yuan")) # 6

    s2 = "1,2,34,100,yuan,rain,alvin,45"
    ret = re.findall("[a-z]+", s2)
    print(ret) # ['yuan', 'rain', 'alvin']

    #################### 元字符 ####################

    # (1) 通配符 .: 默认模式下匹配除了换行符以外的所有符号

    ret = re.findall("y..n", "hello yuan,hello rain,hello yabn")
    print(ret) # ['yuan', 'yabn']
    ret = re.findall("y..n", "hello yu\nn,hello rain,hello yabn", re.S) #修改模式通配符 .: 该模式下匹配所有符号
    print(ret) # ['yu\nn', 'yabn']

    # (2) 重复: * [0,无穷]   +[1,无穷]   ?[0,1] {} 指定范围
    # 重点:默认贪婪匹配
    # 如何取消贪婪匹配

    ret = re.findall("\d", "1,2,3,55,yuan,33")
    print(ret) # ['1', '2', '3', '5', '5', '3', '3']

    ret = re.findall("hi \d{2}", "hi 1,hi 66,hi 188")
    print(ret) # ['hi 66', 'hi 18']

    ret = re.findall("hi \d*", "hi 1,hi 66,hi 188")
    print(ret) # ['hi 1', 'hi 66', 'hi 188']

    ret = re.findall("\d+", "66,188,2,12222,hello")
    print(ret) # ['66', '188', '2', '12222']

    ret = re.findall("\d+?", "66,188,2,12222,hello")  # 取消贪婪匹配?
    print(ret) # ['6', '6', '1', '8', '8', '2', '1', '2', '2', '2', '2']

    ret = re.findall("hi \d?", "hi 1,hi 66,hi 188,hi ")  #
    print(ret) # ['hi 1', 'hi 6', 'hi 1', 'hi ']

    ret = re.findall("hi \d{0,1}", "hi 1,hi 66,hi 188,hi ")  #
    print(ret) # ['hi 1', 'hi 6', 'hi 1', 'hi ']

    ret = re.findall("hi \d{1,}", "hi 1,hi 66,hi 188,hi ")  #
    print(ret) # ['hi 1', 'hi 66', 'hi 188']

    ret = re.findall("hi \d{0,}", "hi 1,hi 66,hi 188,hi ")  #
    print(ret) # ['hi 1', 'hi 66', 'hi 188', 'hi ']

    ret = re.findall("hi \d{1,3}?", "hi 1,hi 66,hi 188,hi ")  #
    print(ret) # ['hi 1', 'hi 6', 'hi 1']


    # (3) ^ $

    ret = re.findall("^good/.{4}/.{4}", "hello/good/food/meat")
    print(ret) # []

    ret = re.findall("^good/.{4}/meat$", "good/aaaa/meat")
    print(ret) # ['good/aaaa/meat']


    # (4) [] 字符集匹配[]中任意一个符号, 字符集两个特殊符号 - 范围 ^: 取反
    ret = re.findall("yu[ac]n", "yuan yubn yucn yuacn")
    print(ret) # ['yuan', 'yucn']

    ret = re.findall("yu[a,c]n", "yuan yubn yucn yu,n")
    print(ret) # ['yuan', 'yucn', 'yu,n']

    ret = re.findall("yu[0123456789]n", "yuan yu8n yucn yu2n")
    print(ret) # print(ret) #

    ret = re.findall("yu[0-9]n", "yuan yu8n yucn yu2n")
    print(ret) # ['yu8n', 'yu2n']

    ret = re.findall("[a-z0-9A-Z]+", "yuan,22,alvin,45,rain")
    print(ret) # ['yuan', '22', 'alvin', '45', 'rain']

    ret = re.findall("[^0-9]+", "yuan,22,alvin,45,rain") #取反
    print(ret) # ['yuan,', ',alvin,', ',rain']

    # (5) 分组() |
    # 取消优先提取 ?:
    ret = re.findall("https?://www\.[a-zA-Z0-9]+\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret)

    # (6) 转义符 \
    # 赋予一些普通符号以特殊功能 [0-9] \d   \w [0-9a-zA-Z]
    # 取消一些特殊符号的特殊功能

    ret = re.findall("\d+","123a45bcd678")
    print(ret)

    # (7) () 分组

    #1.re.findall()
    ret1 = re.findall("https?://www\.\w+\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret1) # ['http://www.baidu.com', 'https://www.jd.com', 'http://www.python.cn']
    ret2 = re.findall("(https?)://www\.\w+\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret2) # ['http', 'https', 'http']

    ret3 = re.findall("https?://www\.(\w+)\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret3) # ['baidu', 'jd', 'python']

    #2.re.search() 查询匹配的第一个结果,返回对象
    ret4 = re.search("https?://www\.\w+\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret4) # <re.Match object; span=(0, 20), match='http://www.baidu.com'>
    print(ret4.group()) # http://www.baidu.com

    ret5= re.search("https?://www\.(?P<mingzi>\w+)\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret5) # <re.Match object; span=(0, 20), match='http://www.baidu.com'>
    print(ret5.group("mingzi")) # baidu

    ret6= re.search("(?P<yuming>https?)://www\.(?P<mingzi>\w+)\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret6.group("yuming")) # http

    ret7= re.search("(?P<yuming>https?)://www\.(?P<mingzi>\w+)\.(?P<houzhui>com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret7.group("houzhui")) # com

    #3.re.match() #开头进行匹配
    ret8= re.match("https?://www\.\w+\.(?:com|cn)",
                     "http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret8.group()) # http://www.baidu.com

    ret9= re.match("https?://www\.\w+\.(?:com|cn)",
                     "huchangxi,http://www.baidu.com,https://www.jd.com,http://www.python.cn,")
    print(ret9.group()) # None
    ====================================

    hashlib加密模块

    在程序中我们经常可以看到有很多的加密算法,比如说MD5 sha1等,今天我们就来了解下这下加密算法的吧,在了解之前我们需要知道一个模块嘛就是hashlib,他就是目前Python一个提供字符加密的模块,它加密的字符类型为二进制编码,所以直接加密字符串会报错。

    import hashlib
    string='任性的90后boy'
    #使用encode进行转换
    sha1 = hashlib.sha1()
    sha1.update(string.encode('utf-8'))
    res = sha1.hexdigest()
    print("sha1采用encode转换加密结果:",res)
    #使用byte转换为二进制
    sha1 = hashlib.sha1()
    sha1.update(bytes(string,encoding='utf-8'))
    res = sha1.hexdigest()
    print("sha1采用byte转换的结果:",res)

    可以使用下列这两种方法任意一种获取到hashlib中所有的散列算法集合:

    import hashlib
    a=hashlib.algorithms_available
    b=hashlib.algorithms_guaranteed
    print(a)
    print(b)
    下面我们挑选常用的集中算法来进行讲解。

    一、MD5
    MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

    MD5算法具有以下特点:

    1、压缩性:任意长度的数据,算出的MD5值长度都是固定的。

    2、容易计算:从原数据计算出MD5值很容易。

    3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

    4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

    MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。

    import hashlib
    string='任性的90后boy'
    md5 = hashlib.md5()
    md5.update(string.encode('utf-8'))#转码,update里的必须是字节型
    res = md5.hexdigest() #返回字符型摘要信息
    print(md5.digest())#返回字节型的摘要信息
    print("md5加密结果:",res)
    二、sha1
    安全散列算法,SHA1的结果是160 bit字节,通常用一个40位的16进制字符串表示

    import hashlib
    string='任性的90后boy'
    sha1 = hashlib.sha1()
    sha1.update(string.encode('utf-8'))
    res = sha1.hexdigest()
    print("sha1加密结果:",res)
    三、sha224
    安全散列算法

    import hashlib
    string='任性的90后boy'
    sha224 = hashlib.sha224()
    sha224.update(string.encode('utf-8'))
    res = sha224.hexdigest()
    print("sha224加密结果:",res)
    四、sha256
    安全散列算法

    import hashlib
    string='任性的90后boy'
    sha256 = hashlib.sha256()
    sha256.update(string.encode('utf-8'))
    res = sha256.hexdigest()
    print("sha256加密结果:",res)
    五、sha384
    安全散列算法

    import hashlib
    string='任性的90后boy'
    sha384 = hashlib.sha384()
    sha384.update(string.encode('utf-8'))
    res = sha384.hexdigest()
    print("sha384加密结果:",res)
    六、sha512
    安全散列算法

    import hashlib
    string='任性的90后boy'
    sha512= hashlib.sha512()
    sha512.update(string.encode('utf-8'))
    res = sha512.hexdigest()
    print("sha512加密结果:",res)
    七、高级加密
    以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。

    md5 = hashlib.md5()
    md5.update('md5'.encode('utf-8'))
    res = md5.hexdigest()
    print("普通加密:",res)
    md51 = hashlib.md5(b'md512')
    md51.update('md51'.encode('utf-8'))
    res = md51.hexdigest()
    print("采用key加密:",res)

    logging日志模块

    很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug(), info(), warning(), error() and critical() 5个级别,对应的5中打印日志的方法分别是:debug、info、warning、error、critical,默认是WARNING,当在WARNING或之上时才被跟踪!

    日志级别(从低到高) 对应数值 对应函数            使用场景描述
    DEBUG          10  logging.debug()  最低级别,常用于调试,查看详细信息,诊断问题才会使用
    INFO          20  logging.info()  用于记录程序中正常运行的一些信息,可以理解为print的使用
    WARNING          30  logging.warning()  警告用户虽然程序还在正常运行,但可能会发生错误
    ERROR          40  logging.error()  程序出现错误,程序中的某些功能已经不能够执行
    CRITICAL       50   logging.critical() 程序出现严重错误,程序已经不能继续运行

    import logging
    # 设置打印日志的级别
    def log2():
       level = logging.DEBUG # DEBUG、INFO、WARNING、ERROR、CRITICAL
       logging.basicConfig(level=level)
       logging.debug('debug,用来打印一些调试信息,级别最低')
       logging.info('info,用来打印一些正常的操作信息')
       logging.warning('waring,用来用来打印警告信息')
       logging.error('error,一般用来打印一些错误信息')
       logging.critical('critical,用来打印一些致命的错误信息,等级最高')

    if __name__ == '__main__':
       log2()

    #logging.basicConfig()
    logging.basicConfig()的参数除了设置日志等级,还有很多其他参数设置!

    logging.basicConfig()的参数:
    参数名称        参数作用说明
    filename
    指定保存日志的文件名,用指定文件名创建一个FileHandler,而不是StreamHandler
    filemode
    如果指定了文件名,则用该模式打开文件,默认是'a'模式
    format
    指定出输出的格式和内容,默认是以冒号分割的levalname、name message
    datefmt
    使用指定的日期/时间格式,与 time.strftime() 所接受的格式相同。
    style
    如果指定了format,则格式字符串的时候使用此风格,%、{$分别对应于printf风格、str.format()、string.Template。默认风格为%
    level
    指定根日志记录器级别,默认为logging.WARNING
    stream
    指定日志的输出流,可以指定输出到sys.stderr,std.stdout 文件,默认输出到sys.stderr。使用指定的流初始化StramHandler,注意:stream和filename参数不兼容,如果两者同时使用,则会引发ValueError错误
    handlers
    如果指定,这应为一个包含要加入根日志记录器的已创建处理器的可迭代对象。 任何尚未设置格式描述符的处理器将被设置为在此函数中创建的默认格式描述符。 请注意此参数与 filename stream 不兼容 —— 如果两者同时存在,则会引发 ValueError。
    force
    如果将此关键字参数指定为 true,则在执行其他参数指定的配置之前,将移除并关闭附加到根记录器的所有现有处理器。
    encoding
    如果此关键字参数与 filename 一同被指定,则其值会在创建 FileHandler 时被使用,因而也会在打开输出文件时被使用。
    errors
    如果此关键字参数与 filename 一同被指定,则其值会在创建 FileHandler 时被使用,因而也会在打开输出文件时被使用。 如果未指定,则会使用值 ‘backslashreplace’。 请注意如果指定为 None,它将被原样传给 open(),这意味着它将会当作传入 ‘errors’ 一样处理。
                                 
    #上面提到的日志的输出格式化参数format,其控制日志的输出的一些格式(参考):
    对应格式 格式描述
    %(levelno)s 日志级别
    %(levelname)s 日志级别名称
    %(pathname)s 当前程序的路径
    %(filename)s 当前程序的名称
    %(funcName)s 日志所属的当前函数
    %(lineno)d 日志的当前行号
    %(asctime)s 日志的时间
    %(thread)s 线程的ID
    %(threadName)s 线程的名称
    %(process)s 进程的ID
    %(message)s 日志的信息
                                 
    例如:
    format=%(levelno)s %(asctime)s %(message)s: %(linno)d
    %(显示的日志内容)s:后面的s表示日志内容是字符串,显示的日志信息之间可以是空格,或者其他连接符号,只要方便自己查看即可!

    #上面的例子是输入日志到控制台,下面例子是输出日志信息到文件中:
    import logging
    def log3():
       logging.basicConfig(filename='./log.txt',
                           format='%(asctime)s-%(name)s-%(levelname)s-%(message)s-%(funcName)s:%(lineno)d',
                           level=logging.ERROR)
                           # encoding='utf-8') # 中文乱码,在python>=3.9才有该参数
       logging.debug('debug,用来打印一些调试信息,级别最低')
       logging.info('info,用来打印一些正常的操作信息')
       logging.warning('waring,用来用来打印警告信息')
       logging.error('error,一般用来打印一些错误信息')
       logging.critical('critical,用来打印一些致命的错误信息,等级最高')
    if __name__ == '__main__':
       log3()                      

    socket数据交互模块

    该模块专门用于计算机之间的远程数据交互

    socket基本操作
    import socket
    # 1.产生一个socket对象
    server = socket.socket()  # 括号内不传参数 默认采用的网络协议是TCP协议(后续可自行了解)
    # 2.绑定一个固定的地址(IP PORT)
    """
    IP地址:接入互联网的计算机都必须有一个IP地址 相当于身份证号
    PORT号:计算机用于管理自身多个应用程序的方式
    """
    server.bind(('127.0.0.1', 8080))  # 127.0.0.1是本地回环地址 只有自己的计算机才可以访问
    # 3.半链接池(节省资源)
    server.listen(5)
    # 4.等待客户端链接
    sock, addr = server.accept()  # sock用于数据交互 addr客户端地址
    # 5.朝客户端发送数据
    sock.send(b'hello I am from server')
    # 6.接收客户端的数据
    data = sock.recv(1024)
    print('客户端发送过来的数据:',data)


    import socket
    # 1.产生一个socket对象
    client = socket.socket()
    # 2.链接服务端(IP PORT)
    client.connect(('127.0.0.1', 8080))
    # 3.接收服务端发送过来的数据
    data = client.recv(1024)
    print('来自于服务端的数据:',data)
    # 4.朝服务端发送数据
    client.send(b'hello I am from client')
     
  • 相关阅读:
    IE6 PNG透明终极解决方案(打造W3CfunsIE6PNG最强帖)
    python处理异常(1) 分类: python 20130116 17:59 274人阅读 评论(0) 收藏
    输出列表中出现次数最多的元素 分类: python 20130115 15:25 990人阅读 评论(0) 收藏
    python性能优化摘录 分类: python 20130117 18:01 1192人阅读 评论(0) 收藏
    Pyscripter下载地址及UnicodeEncodeError: 'ascii' codec解决方法 分类: software 问题总结 20130116 15:41 3384人阅读 评论(0) 收藏
    python性能优化摘录(二) 分类: python 20130118 11:27 291人阅读 评论(0) 收藏
    python简明教程os模块 分类: python 20121227 11:54 200人阅读 评论(0) 收藏
    转换时间格式 及 列表综合 分类: python 20121226 17:54 182人阅读 评论(0) 收藏
    lambda()函数 分类: python 20121227 18:01 569人阅读 评论(0) 收藏
    file()创建文件方法 分类: python python基础学习 20121224 18:17 239人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/A121/p/16631753.html
Copyright © 2020-2023  润新知