常用模塊


自定義模塊:

  • 什么是模塊:一個.py文件就是模塊,節省代碼,容易維護,組織結構更清晰

  • 模塊的運行方式:

    • 腳本方式:直接用解釋器執行,或者pycharm中右鍵運行。

    • 模塊方式:被其他的模塊導入,為導入他的模塊提供資源(變量,函數定義,)

常用的模塊:

  • json 不同語言之間序列化

  • pickle pyton語言使用,支持序列化數據類型多

  • sys 與python解釋器交互的,解決變量路徑問題

  • os 文件目錄操作,操作系統底層函數

  • hashlib 加密模塊

  • time 時間模塊

  • datetime 時間模塊,查找之前之后時間使用的較多

  • rendom 取隨機值

  • logging 記錄日志

  • collections 定義特殊的數據類型

  • re 正則

  • subprocess 執行windows端命令

模塊的分類:

  • 內置模塊:標准庫,python解釋器自帶的,time,os,sys,等等200多種
  • 第三方庫(模塊):各種大神寫的模塊,通過pip install...安裝的6000多種
  • 自己寫的模塊,自定義模塊

引用模塊發生三件事:

  • 1,import haiyang將haiyang.py文件(變量,函數名)加載到內存
  • 2,在內存中創建一個以haiyang命名的名稱空間
  • 3,通過haiyang.xx名稱空間的名字.等方式引用此模塊的名字(變量,函數名)

引用多個模塊:

  • import os
  • import sys #引用多個模塊時,要逐行引用

import haiyang:

  • 當我引用haiyang模塊的時候,實際上將haiyang.py執行一遍,加載到內存
    通過import引用的模塊,他有自己的獨立名稱空間,與當前執行文件沒有關系。
    
    執行文件:02 模塊 import
    被引用文件(模塊):haiyang.py
    為模塊起別名:
    import  haiyang as ab
    print(ab.name)
    

from haiyang import *:

  • 示例1:被引用文件(模塊)all進行限制引用者使用范圍

  • 引用者:
    from haiyang import *
    
    模塊:
    __all__ = ['name']
    name = "huhaiyang"
    
  • 工作中錯誤示例:

  • from haiyang import name:
    from haiyang import *
    相當於從haiyang模塊的全局空間中將name變量與值得對應關系,復制到當前執行文件的全局空間中
    引用模塊中的函數,如果此函數修改一些變量,這些變量還是從此模塊中尋找,不會改變當前執行文件變量
    
    優點:調用更方便
    缺點:引用變量跟當前文件變量沖突
    

py文件的兩種功能:

  • 1.py文件的第一個功能:執行文件(承載代碼)腳本,直接打印`__name__`返回`__main__`
    
    2.py文件的第二個功能:模塊(被動執行文件),直接打印`__name__`返回模塊名
    
    作用:當你在被執行文件中,引用模塊后,返回的是模塊名,模塊中進行了`if __name__ == '__main__':`
    判斷的話,被執行者是不會執行此函數(控制函數自動調用),模塊中可以進行測試代碼    
    

尋找一個模塊的路徑:

  • 內存中 >>> 內置模塊 >>> sys.path
  • 只要這三個地方存在,就可以進行加載這個模塊

不同目錄加載模塊;

  • 將路徑加載到sys.path中,以絕對路徑導入。

  • import sys
    sys.path.append(r'E:\Python-學習\')
    import haiyang
    
    print(haiyang.name)
    

包的使用:

  • 一個文件其實就是有個包

  • 創建一個包 new-package,會自行創建一個·__init__文件·

  • 創建包過程:

    • 1.將該aaa包內__init__.py文件加載到內存

    • 2.創建一個以aaa,命名的名稱空間

    • 3.通過aaa. 的方式引用__init__的所有名字

  • 首先,無論在哪里引用模塊,import或者from .. import..

  • 最開始的模塊或者包的內存,每只sys,path中能找到的

  • 直接import 為了讓我們會使用包里面的__init__

  • import 導入包以及包內的功能:

    • 示例1:簡單的包引用

    • bolg
      |____ aaa
      |    |__ __init__.py   #from aaa import m1
      |    |__ m1.py         #定義函數func
      |
      |____ run.py         #aaa.m1.func()
      
      aaa目錄文件m1 定義func函數:
      aaa目錄__init__文件中定義:from aaa import m1
      
      import aaa
      #1.在執行文件寫入import aaa
      #2.aaa的__init__里面寫入 from aaa import m1
      #3.然后執行aaa.m1.a
      
      aaa.m1.func()
      
    • 示例2:多層目錄引用__init__

    • #在當前文件中,引用aaa包下的bbb包的變量name
      #1.在執行文件寫入import aaa
      #2.aaa的__init__里面寫入 from aaa import bbb
      #3.bbb的__init__里面寫入一個變量 name ="海洋"
      #4.然后執行aaa.bbb
      
      import aaa
      print(aaa.bbb.name)
      
    • 示例3:多層目錄引用變量

    • bolg
      |____aaa
      |    |__bbb
      |    |  |__ __init__.py   #相對from ..bbb import m3 或者 from .mb import func3
      |    |  |__ m3.py         #func3函數
      |    | 
      |    |__ __init__.py      #from aaa import bbb/from aaa import m1
      |    |__ m1.py            #func1函數
      |    |__ m2.py
      |
      |____ run.py
      
      #在當前文件中,引用aaa包目錄下的bbb包的變量name
      #1.在執行文件寫入import aaa
      #2.在aaa的__init__里面寫入 from aaa import bbb (bbb包里面的__init__里面可以引用)
      #3.在bbb包的__init__寫入 from  aaa.bbb import m3
      #4.然后執行aaa.bbb.m3.func3()
      
      import aaa.bbb
      aaa.bbb.m3.func3()  #調用aaa下bbb下m3
      aaa.bbb.func3()     #init直接引用func3函數時不用加mb
      aaa.m1.func1()      #調用aaa目錄下的m1
      
  • from ... import .... 導入包以及包內的功能

    • 這種方式不用設置__init__文件

    • # from a.b.c import d.e.f
      # c的前面必須是個包
      # import 的后面一定是名字,並且不能再有點
      
      #第一種直接引用目錄文件下的變量
      from  aaa.bbb.m2 import  func1
      func1()
      
      #第二種直接引用目錄下的文件
      from aaa.bbb import m2
      m2.func1()
      
      

  • 模塊划整一個包:

    • # 由於nb模塊增加了很多很多功能,所以我們nb這個文件就要划整一個包,
      # 無論對nb模塊有任何操作,對於使用者來說不應該改變,極少的改變對其的調用.
      bolg
      |____ nb
      |    |__ __init__.py 
      |    |__ m1.py        #函數f1,f2
      |    |__ m2.py       #函數f3
      |
      |____ run.py
      
      __init__.py存放:
      from nb.m1 import f1,f2
      from nb.m2 import f3
      
      執行文件:
      run.py  執行:nb.f1() nb.f2() nb.f3()
      
      
  • 多層目錄引用:

    • bolg         #第一層
      |____NB      #第二層
      |    |__dsb  #第三層
      |    |    |__ly       #f3
      |    |__ __init__.py  
      |    |__ m1.py        #f1函數 
      |    |__ m2.py        #f2函數
      |
      |____ run.py
      
      #__init__存放
      from .m1 import f1
      from .m2 import f2
      from .dsb.ly import f3
      
      #執行文件:
      #第一種運行方法,將目錄添加到sys.path
      # import sys
      # sys.path.append(r'E:\相對導入絕對導入\bolg')
      import NB as nb
      nb.f1()
      nb.f2()
      nb.f3
      
      #第二種運行方法:
      import dir.NB as nb
      nb.f1()
      nb.f2()
      nb.f3()
      
      

模塊使用:

序列化模塊:

  • 序列化模塊:將一種數據結構 (list,dict) 轉化成一個特殊的序列(特殊的字符串,bytes)的過程

    ​ 並且還可以翻轉回去。

  • 為什么要有序列化:

    • str(list)字符串存儲到文件中,讀取出來,反轉不回去
    • 凡是數據通過網絡傳出去最終格式必須是bytes類型
  • json模塊:

  • 支持python數據結構有限:int str list dict tuple bool none float

  • pickle模塊:

    • 支持python中所有的數據類型以及對象,只能是python語言中使用的
  • shevle模塊:

    • 只能是文件存取

json模塊方法:

  • dumps序列化: loads 反序列化(主要用於網絡傳輸和多文件存取)

  • import json
    dic = {'username':'海洋'}
    ret = json.dumps(dic)
    print(ret)
    
    ret1 = json.loads(ret)
    print(ret1)
    
    特殊參數
    import json
    dic = {'username': '海洋', 'password': 123,'status': False}
    ret = json.dumps(dic,ensure_ascii=False,sort_keys=True)
    ret1 = json.loads(ret)
    
    print(ret,type(ret))
    print(ret,type(ret1))
    
    #文件存取:
    import json
    dic = {'username': '海洋', 'password': 123,'status': False}
    
    with open("jsontest",encoding='utf-8',mode='w') as f1:
         ret = json.dumps(dic)
         f1.write(ret)
    
    with open("jsontest", encoding='utf-8') as f1:
        ret2 = json.loads(f1.read())
        print(ret2)
    
    
  • 多個文件存儲使用dumps:

  • import json
    dic1 = {'username': '海洋', 'password': 123,'status': False}
    dic2 = {'username': '俊麗', 'password': 123,'status': False}
    dic3 = {'username': '寶寶', 'password': 123,'status': False}
    
    with open("jsontest",encoding='utf-8',mode='a') as f1:
         f1.write(f"{json.dumps(dic1)}\n{json.dumps(dic2)}\n{json.dumps(dic3)}\n")
    
    with open("jsontest", encoding='utf-8') as f1:
        for line in f1:
            ret = json.loads(line)
            print(ret,type(ret))
    
    
  • dump load:只能用於單個數據的存儲文件(不常用 )

  • #不需要先轉換字符串,節省一些代碼
    import json
    dic = {'username': '海洋', 'password': 123,'status': False}
    
    with open("jsontest",encoding='utf-8',mode='w') as f1:
         json.dump(dic,f1)
    
    with open("jsontest", encoding='utf-8') as f1:
        dic1 = json.load(f1)
        print(dic1)
    

pickle模塊:

  • dumps,loads:(只能是網絡傳輸)

  • import pickle
    l1 = ["海洋",'俊麗',888]
    
    l2 = pickle.dumps(l1)
    l3 = pickle.loads(l2)
    print(l2)
    print(l3)
    
  • dump load:(只能數據結構存取文件)

  • import pickle
    l1 = ["海洋",'俊麗',888]
    
    with open("jsontest",mode='wb') as f1:
        pickle.dump(l1,f1)
    
    with open("jsontest",mode='rb') as f2:
        ret = pickle.load(f2)
        print(ret,type(ret))
    
  • dump load:(pickle 多個文件寫入)

  • import pickle
    l1 = ["海洋",'俊麗',888]
    l2 = ["海洋",'俊麗',888]
    l3 = ["海洋",'俊麗',888]
    
    with open("jsontest",mode='wb') as f1:
        pickle.dump(l1,f1)
        pickle.dump(l2,f1)
        pickle.dump(l3,f1)
    
    with open("jsontest",mode='rb') as f2:
        ret1 = pickle.load(f2)
        ret2 = pickle.load(f2)
        ret3 = pickle.load(f2)
        print(ret1,ret2,ret3,type(ret1))
    
  • pickle 對象寫入文件:

  • #寫入
    with open(settings.register_student,mode="ab") as f3:
         pickle.dump(obj_write,f3)
    #讀取
    with open(settings.register_student,mode="rb") as f4:
          while 1:
               try:
                   ret1 = pickle.load(f4)
                    yield ret1
               except Exception:
                    break
    
    

sys模塊:(路徑)

  • import sys
    print(sys.path)      #獲取當前路徑
    print(sys.version)   #獲取python版本
    1
    for i in range(3):
        print(i)
    sys.exit() #主動退出
    exit()  
    print(111)
    
    sys.path.append(路徑)  #與python解釋器進行交互,解決變量路徑問題
    

os模塊:(文件,目錄)

  • 工作目錄:當前目錄,父級目錄(上層目錄)

  • #操作系統底層函數的方法
    import os
    # 查看當前工作目錄和切換目錄
    print(os.getcwd())
    print(os.chdir("路徑"))  #切換目錄,相當於shell的cd
    print(os.curdir)        #返回當前目錄名
    print(os.pardir)        #返回當前目錄的父目錄字符串名
    
    
    # 和文件夾相關
    os.makedirs("haiyang/haha")     #在當前目錄生成目錄可以生成多層,類似mkdir -p
    os.removedirs('目錄')            #若目錄為為空則刪除,不為空刪除不了
    os.mkdir('目錄')                 #生成單級目錄
    os.rmdir('目錄')                 #刪除單級空目錄,為空無法刪除
    print(os.listdir('haiyang'))    #列出指定目錄下的所有文件和子目錄,以列表的方式
    
    
    # 和文件相關
    os.remove("file")               #刪除文件
    os.rename('舊文件','新文件')      #重命名文件
    print(os.stat('jsontest'))      #獲取文件/目錄信息
    
    
    # path和路徑相關
    # print(os.path.abspath('jsontest'))   #返回當前的絕對路徑
    
    #將當前的絕對路徑轉化為列表,前面為路徑,后面為文件名
    # print(os.path.split(os.path.abspath('jsontest')))  
    # print(__file__)    #動態獲取當前文件的絕對路徑
    
    # 獲取當前文件的爺爺級目錄
    # print(os.path.dirname(os.path.abspath('jsontest')))   #獲取父級目錄
    # print(os.path.basename(os.path.abspath('jsontest')))   #返回一個路徑最后的文件名
    
    
    # 判斷路徑
    # os.path.join("路徑1",'路徑2')   #將多個路徑拼接組合
    # print(os.path.isfile(os.path.abspath('jsontest')))  #判斷路徑是否是文件  在返回True
    # print(os.path.isdir(os.path.abspath('jsontest')))   #判斷路徑是否目錄  在返回True
    # print(os.path.exists(os.path.abspath('jsontest')))  #判斷當前路徑是否存在  在返回True
    # print(os.path.isabs(os.path.abspath('jsontest')))   #判斷是否是絕對路徑   在返回True
    
    
    # print(os.path.getatime('文件或者目錄'))               #查看文件或者目錄最后訪問時間
    # print(os.path.getmtime('文件或者目錄'))               #查看文件或者目錄最后修改時間
    # print(os.path.getsize("文件或者目錄"))                #查看文件或者目錄大小
    
    

hashlib模塊:(加密)

  • 加密模塊,摘要算法,散列算法,等等

  • 加密過程:

    • 1,將一個bytes類型的數據,通過hashlib進行加密返回,一個等長度的16進制數字
    • 2,過程不可逆
    • 3,相同的bytes類型的數據通過相同的加密方法得到的數據絕對相同
    • 4,不相同的bytes類型的數據通過相同的加密方法得到的數據也絕對不相同
  • 加密示例:

    • import hashlib
      ret = hashlib.md5()
      ret.update('海洋'.encode('utf-8'))
      print(ret.hexdigest())
      
      
  • 加鹽示例:

    • import hashlib
      ret = hashlib.md5("俊麗".encode('utf-8'))   #俊麗鹽
      ret.update('海洋'.encode('utf-8'))
      print(ret.hexdigest())
      
      
  • 動態加鹽示例:

    • import hashlib
      username = input("輸入用戶名:").strip()
      password = input('輸入密碼').strip()
      ret = hashlib.md5(username.encode('utf-8'))   #動態的用戶名
      ret.update('海洋'.encode('utf-8'))
      print(ret.hexdigest())
      
      
  • sha系列加密:

    • #sha系列:安全系數高,耗時高
      import hashlib
      username = input("輸入用戶名:").strip()
      password = input('輸入密碼').strip()
      ret = hashlib.sha3_512(username.encode('utf-8'))
      ret.update('海洋'.encode('utf-8'))
      print(ret.hexdigest())
      
      
  • 文件校驗:

    • import hashlib
      def md5_file(path):
          ret = hashlib.md5()
          with open(path,mode='rb') as f1:
              while 1:
                  content = f1.read(1024)   #每次讀取文件
                  if content:
                      ret.update(content)
                  else:
                      return ret.hexdigest()
      
      print(md5_file('python-3.7.4rc1-embed-win32.zip'))
      
      

time模塊:(時間)

  • 三種形式:

    • 1,時間戳:time.time() 格林威治時間,時差,計時 1561696705.6334207
    • 2,人類看的懂的時間,格式化時間, 2019-6-28 12:00
    • 3,結構化時間:python語言使用的,解釋器使用的 time.struct_time(tm_year=2019, .....
  • 格式化時間:

    • #%Y年 %m月 %d日  %H時  %M分 %S秒
      
      print(time.strftime("%Y-%m-%d %H:%M:%S" ))     #字符串類型的格式化時間
      print(time.strftime("%Y-%m-%d %H:%M:%S %A" ))  #字符串類型的格式化時間
      
      
  • 時間戳轉換格式化時間

    • timetamp = time.time()
      st = time.localtime(timetamp)
      # print(st)
      time1 = time.strftime('%Y/%m/%d %H:%M:%S',st)
      print(time1)
      
      
  • 格式化時間轉化成時間戳

    • import time
      ft = time.strftime('%y/%m/%d %H:%M:%S')
      # print(ft)
      st = time.strptime(ft,'%y/%m/%d %H:%M:%S')
      timestamp = time.mktime(st)
      print(timestamp)
      
      

datetime模塊:

  • 查找之前的時間:

    • import datetime
      time1 = datetime.datetime.now()        #現在的時間
      print(datetime.datetime.now() + datetime.timedelta(weeks=3))  #三周前
      
      print(current_time.replace(year=1977))   #調整到指定年月
      
      
  • 將時間戳轉化成時間:

    • print(datetime.date.fromtimestamp(1232132131))
      
      

random模塊:

  • 隨機取值

    • import random
      #隨機字符串隨機發紅包時使用
      print(random.random())           #大於0小於1之間的小數
      print(random.uniform(1,6))       #隨機取1-6的小數
      print(random.randint(1,5))       #1-5隨機取值
      print(random.randrange(1,10,2))  #顧頭不顧尾
      
      print(random.choice(['海洋','俊麗','寶寶']))  #可迭代對象隨機取列表值
      print(random.sample(['海洋','俊麗','寶寶'],2)) #可迭代對象隨機取列表值,2選兩個
      
      item = [i for i in range(10)]   #原列表打亂順序
      random.shuffle(item)
      print(item)
      
      

logging模塊:

  • 系統日志:記錄服務器的一些重要信息,監控系統,網卡流量,記錄操作信息等等。
  • 網站日志:訪問異常,卡頓,網站一些板塊,受歡迎程度,訪問量,點擊率,等等。
  • 錯誤日志:開發人員在開發項目中利用日志進行排錯,排除一些避免不了的錯誤,輔助開發
  • 記錄用戶信息日志:用戶的消費習慣,新聞偏好等等(數據庫解決)

  • 三個版本:
    • 1.low版 (簡易版)
    • 2.標配版(標配版)
    • 3.旗艦版(項目中使用的,Django項目)

  • low版:

    • #缺點:文件與屏幕輸出只能選擇一個
      
      import logging
      logging.basicConfig(                   #設置級別才會出現info和debug
          # level=logging.DEBUG,
          level=30,                          #設置日志級別,可以調整
          format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', #日志格式
          filename=r'test.log',            #寫入日志
      )
      logging.debug('調試模式')         #調試
      logging.info('信息信息')          #信息
      logging.warning('警告信息')       #警告
      logging.error('錯誤信息')         #錯誤
      logging.critical('嚴重錯誤')      #關鍵
      
      
  • 標配版:

    • #文件和屏幕都可以輸入
      import logging
      
      logger = logging.getLogger()                                #創建一個logger對象
      fh = logging.FileHandler('標配版.log',encoding='utf-8')      #創建文件對象
      sh = logging.StreamHandler()                                #創建屏幕對象
      
      #創建顯示格式:
      formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
      fh.setFormatter(formatter)       #綁定顯示格式
      sh.setFormatter(formatter)
      
      logger.addHandler(fh)            #logger對象添加多個fh,ch對象
      logger.addHandler(sh)
      
      # logger.setLevel(10)            #總開關,不寫默認級別30,先寫總開關
      # fh.setLevel(30)
      # sh.setLevel(10)
      
      logging.debug('調試模式')         #調試
      logging.info('信息信息')          #信息
      logging.warning('警告信息')       #警告
      logging.error('錯誤信息')         #錯誤
      logging.critical('嚴重錯誤')      #關鍵
      
      
  • 旗艦版:

    • 自定制(通過字典的方式)日志

    • 輪轉日志的功能

    • import logging.config    #引用配置文件/模塊
      
      # 定義三種日志輸出格式 開始
      standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                        '[%(levelname)s][%(message)s]'   #其中name為getlogger指定的名字
      simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
      id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'   #級別/時間/信息
      # 定義日志輸出格式 結束
      
      
      #寫入日志路徑和日志名稱
      logfile_name = 'log1.log'
      logfile_path = r"E:\Python-學習\作業\23期\day19-包的導入-login日志\日志\log1.log"
      
      
      # log配置字典
      #LOGGING_DIC第一層key不能改變
      LOGGING_DIC = {
          'version': 1,                                 #版本號
          'disable_existing_loggers': False,            #固定寫法
          'formatters': {                               #日志格式
              'standard': {                             #標准格式
                  'format': standard_format
              },
              'simple': {                               #簡單格式
                  'format': simple_format
              },
          },
          'filters': {},                                #過濾
          'handlers': {
              #打印到終端的日志
              'sh1': {                                  #終端日志打印到屏幕
                  'level': 'DEBUG',                     #debug開始打印
                  'class': 'logging.StreamHandler',
                  'formatter': 'simple'
              },
              #打印到文件的日志,收集info及以上的日志
              'staff_fh': {                                              #寫到文件信息
                  'level': 'DEBUG',
                  'class': 'logging.handlers.RotatingFileHandler',       # 保存到文件
                  'formatter': 'standard',                               # 選擇復雜的格式
                  'filename': logfile_path,                              # 日志文件
                  'maxBytes': 3000,        # 日志大小字節 5M1024*1024*5
                  'backupCount': 5,
                  'encoding': 'utf-8',     # 日志文件的編碼,再也不用擔心中文log亂碼了
              },
              'boss': {  # 寫到文件信息
                  'level': 'DEBUG',
                  'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                  'formatter': 'standard',                          # 選擇復雜的格式
                  'filename': logfile_path,                         # 日志文件
                  'maxBytes': 3000,  # 日志大小字節 5M1024*1024*5
                  'backupCount': 5,
                  'encoding': 'utf-8',  # 日志文件的編碼,再也不用擔心中文log亂碼了
              },
          },   #句柄
          'loggers': {
              #logging.getLogger(__name__)拿到的logger配置
              '': {
                  'handlers': ['staff_fh', 'sh1','boss'],  # 這里把上面定義的兩個handler都加上,即log數據既寫入文件又打印到屏幕
                  'level': 'DEBUG',
                  'propagate': True,        # 向上(更高level的logger)傳遞
              },
          },                 #產生幾個log
      }
      
      
      def load_my_logging_cfg(task_id):
          logging.config.dictConfig(LOGGING_DIC)    #通過你寫的字典方式配置日志/第一步
          logger = logging.getLogger(task_id)       # 生成一個log實例/
          return logger
      
      def login():
          logging1 = load_my_logging_cfg("登錄功能")
          logging1.info("海洋登錄信息")
      
      def transfer():
          logging2 = load_my_logging_cfg("轉賬功能")
          logging2.info("張三給李四轉賬成功")
      
      login()
      transfer()
      
      
  • 旗艦版日志(函數):

    • import logging.config  
      def student_log(info,task_id):
          standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                            '[%(levelname)s][%(message)s]'
          simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
      
          logfile_name = "student_info.log"
          logfile_path = os.path.join(settings.register_logs,logfile_name)
      
          LOGGING_DIC = {
              'version': 1,
              'disable_existing_loggers': False,
              'formatters': {
                  'standard': {
                      'format': standard_format
                  },
                  'simple': {
                      'format': simple_format
                  },
              },
              'filters': {},
              'handlers': {
                  'staff_fh': {
                      'level': 'DEBUG',
                      'class': 'logging.handlers.RotatingFileHandler',
                      'formatter': 'standard',
                      'filename': logfile_path,
                      'maxBytes': 3000000,
                      'backupCount': 5,
                      'encoding': 'utf-8',
                  },
              },   #句柄
              'loggers': {
                  '': {
                      'handlers': ['staff_fh'],
                      'level': 'DEBUG',
                      'propagate': True,
                  },
              },
          }
      
          logging.config.dictConfig(LOGGING_DIC)   #字典的配置信息
          logger = logging.getLogger(task_id)      #生成一個log實例
          logger.info(info)                        
          
      common.student_log(f"{self.name}創建了課程{ke_name}","創建課程功能") #調用日志
      
      

collections模塊:

  • 給我們提供一下python數據類型,比較特殊的數據類型,出奇制勝

  • 1.namedtuple: 生成可以使用名字來訪問元素內容的tuple(自定義類型)

    • #命名元祖
      from collections import namedtuple
      Point = namedtuple("point",['x','y'])  #"point" 自定義類型
      print(type(Point))
      p = Point(1,2)         #鍵值對存儲
      print(type(p))
      print(p)
      print(p[0])		       #索引取值
      
      
  • 2.deque: 雙端隊列,類似於列表的一種容器性數據,插入元素,刪除元素,效率高

    • from collections import deque
      #從后面添加
      q = deque(['a',1,'c','d'])
      q.append('e')
      print(q)
      
      #在前面添加
      q.appendleft("66")
      q.appendleft("77")
      q.pop()       #默認刪除最后一個
      q.popleft()   #默認刪除最前面的
      print(q)
      
      #按照索引刪
      def q[2]
      print(q)
      
      
  • 3.Counter: 計數器,主要用來計數

    • from collections import  Counter
      
      c = Counter("sdagdjashdaskd")
      print(c)
      
      
  • 4.OrderedDict: 有序字典

    • from collections import OrderedDict
      od = OrderedDict()
      od['z'] = 1
      od['y'] = 2
      od['x'] = 3
      print(od.keys())
      
      
  • 5.defaultdict 帶有默認值的字典

    • from  collections import defaultdict
      #not in方式
      l1 = [11,22,33,44,55,77,88,99]
      dic = {}
      for i in l1:
          if i < 66:
              if "key1" not in dic:
                  dic['key1'] = []
              dic['key1'].append(i)
          else:
              if 'key2' not in dic:
                  dic['key2'] = []
              dic['key2'].append(i)
      print(dic)
      
      #defaultdict方式
      l1 = [11,22,33,44,55,77,88,99]
      dic = defaultdict(list)
      for i in l1:
          if i < 66:
              dic['key1'].append(i)
          else:
              dic['key2'].append(i)
      print(dic)
      
      

re模塊:

  • 正則表達式:從字符串中找出你想要的字符串

    • 在於對你想要得找個字符串進行一個精確的描述
    • 使用在爬蟲中
  • 單個字符匹配:
    • #\W與w
      #\w 數字字母下划線中文
      #\W 非數字字母下划線中文
      print(re.findall("\w",'海洋jx 12*() _'))  #['海', '洋', 'j', 'x', '1', '2', '_']
      print(re.findall("\W",'海洋jx 12*() _'))  #[' ', '*', '(', ')', ' ']
      
      #\s 空格 換行符
      #\S 非空格 換行符
      print(re.findall('\s','海洋haiyang*(_ \t \n'))  #[' ', '\t', ' ', '\n']
      print(re.findall('\S','海洋haiyang*(_ \t \n'))  #['海', '洋', 'h', 'a'.....
      
      #\d  匹配數字 \d\d匹配兩個字符
      #\D  匹配非數字 \d\d匹配兩個字符
      print(re.findall('\d','12345 hai*(_'))  #['1', '2', '3', '4', '5']
      print(re.findall('\D','12345 hai*(_'))  #[' ', 'h', 'a', 'i'.....
      
      #\A  匹配以什么開頭
      # ^
      print(re.findall('\Ahello','hello 胡海洋 -_- 666'))    #['hello']
      print(re.findall('^hello','hello 胡海洋 -_- 666'))     #['hello']
      
      # \Z、\$ 匹配以什么結尾
      print(re.findall('666\Z','hello 海洋 *-_-* \n666'))   #['666']
      print(re.findall('666$','hello 海洋 *-_-* \n666'))    #['666']
      
      # \n 與 \t 匹配\n 與 \t
      print(re.findall('\n','hello \n 海洋 \t*-_-*\t \n666'))  # ['\n', '\n']
      print(re.findall('\t','hello \n 海洋 \t*-_-*\t \n666'))  # ['\t', '\t']
      
      
  • 元字符匹配:
    • #. ? * + {m,n} . * .*?
      #. 匹配任意字符
      #如果匹配成功,光標則移動到下一位
      #如果為匹配成功,光標向下移動一位
      print(re.findall('a.b', 'aabbb,ab aab a*b aaab a海b')) ['aab', 'aab',....
                                                             
      #? 匹配0個或者1個 由左邊字符定義的片段,不是ab 就是b(不匹配a)
      print(re.findall('a?b', 'aabbb,ab aab a*b aabb a海b' ))
                                                             
      # * 匹配0個或者多個左邊字符表達式。 滿足貪婪匹配 
      print(re.findall('a*b', 'ab aab aaab abbb'))
      print(re.findall('ab*', 'ab aab aaab abbbbb'))            
                                                             
      # + 匹配1個或者多個左邊字符表達式。 滿足貪婪匹配 
      print(re.findall('a+b', 'ab aab aaab abbb'))  # ['ab', 'aab', 'aaab', 'ab']       
      
      # {m,n}  匹配m個至n(n能取到)個左邊字符表達式。 滿足貪婪匹配
      print(re.findall('a{2,4}b', 'ab aab aaab aaaaabb'))  # ['aab', 'aaab']
                                             
      
      
  • 貪婪匹配:
    • #.*  貪婪匹配 從頭到尾,必須要a開頭b結尾,中間全部匹配,貪婪匹配
      #.換行符不匹配
      print(re.findall('a.*b', 'ab aab a*()b'))  # ['ab aab a*()b']
      #換行符也可以匹配
      print(re.findall('a.*b', 'ab aab a*()b',re.DOTALL))  # ['ab aab a*()b']
      
      
  • 非貪婪匹配:
    • # .*? 此時的?不是對左邊的字符進行0次或者1次的匹配,
      # 而只是針對.*這種貪婪匹配的模式進行一種限定:告知他要遵從非貪婪匹配 推薦使用!
      # a到b就匹配也就是0個或者多個
      print(re.findall('a.*?b', 'ab a1b a*()b, aaaaaab'))  # ['ab', 'a1b', 'a*()b']
      
      # []: 括號中可以放任意一個字符,一個中括號代表一個字符
      print(re.findall('[ab]', 'a1b a3b aeb a*b arb a_b'))             #匹配里面的a或者b
      print(re.findall('a[abc]b', 'aab abb acb adb afb a_b'))          #匹配前后加[]里面一個
      print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b'))           #數字
      print(re.findall('a[a-z]b', 'a1b a3b aeb a*b arb a_b'))           #小寫
      print(re.findall('a[a-zA-Z]b', 'aAb aWb aeb a*b arb a_b'))        #大小寫
      print(re.findall('a[0-9][0-9]b', 'a11b a12b a34b a*b arb a_b'))  #符合a[][]b里面的兩個數字
      print(re.findall('a[*-+]b','a-b a*b a+b a/b a6b'))                #取符號
      
      #當你想匹配- 時,要把他放在[]里面的最前面
      print(re.findall('a[-*$]b','a-b a$b a*b'))
      
      #^ 在[]中表示取反的意思.
      print(re.findall('a[^0-9]b', 'a1b a3b aeb a*b arb a_b'))
      
      
      
  • 分組:
    • #()分組取
      s = 'haiyang_sb junli_sb baobao_sb haha_nb xixi_sb dd_sb'
      print(re.findall('(\w+)_sb',s))
      
      #|匹配左邊或者右邊
      print(re.findall('haiyang|junli', 'haiyangjunli'))
      
      
      #先把分組去掉篩選,在返回ies和y
      print(re.findall('compan(y|ies)',
                       'Too many companies have gone bankrupt, and the next one is my company'))
      
      #(?):將全部的內容返回,而不是將組內的內容返回,companies|company道理一樣
      print(re.findall('compan(?:y|ies)',
                       'Too many companies have gone bankrupt, and the next one is my company'))
      
      
      
      
  • re常用方法:
    • findall 全部找到以列表返回

    • print(re.findall('a', 'alexwusirbarryeval'))  # ['a', 'a', 'a']
      
      

    • search 找到第一個符合條件的字符串就返回,通過.group()返回

    • print(re.search('sb|alex', 'alex sb sb barry 日天'))
      print(re.search('alex', 'alex sb sb barry 日天').group())
      
      

    • match:None,從字符串開頭匹配,如果第一個條件字符串符合規則則返回,否則返回none

    • print(re.match('barry', 'barry alex wusir 日天'))
      print(re.match('barry', 'barry alex wusir 日天').group())
      
      
    • split 分割 可按照任意分割符進行分割:

    • print(re.split('[ ::,;;,]','alex wusir,日天,太白;女神;肖鋒:吳超'))
      
      
    • sub 替換:

    • print(re.sub('俊麗', '海洋', '俊麗是最好的'))
      
      
    • 自定義obj:

    • obj=re.compile('\d{2}')
      
      print(obj.search('abc123eeee').group())  #12
      print(obj.findall('abc123eeee'))         #['12'],重用了obj自定義obj:
      
      
    • finditer 迭代器返回

    • ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一個存放匹配結果的迭代器
      print(ret)                               # <callable_iterator object at 0x10195f940>
      print(next(ret).group())                 #查看第一個結果
      print(next(ret).group())                 #查看第二個結果
      print([i.group() for i in ret])         #查看剩余的左右結果
      

subprocess:

  • 調用示例:

    • #dir為調用的命令
      import subprocess
      
      obj = subprocess.Popen('dir',
                             shell=True,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             )
      
      print(obj.stdout.read().decode('gbk'))  # 正確命令
      print('error:',obj.stderr.read().decode('gbk'))  # 錯誤命令
      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM