自定義模塊:
-
什么是模塊:一個.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')) # 錯誤命令
-