閱讀目錄:
一、time模塊
二、datetime模塊
三、random模塊
四、os模塊
五、sys模塊
六、shutil模塊
七、shelve模塊
八、suprocess 模塊
九、paramiko模塊
十、configparser模塊
十二、logging模塊
十三、序列化模塊 json&pickle模塊
十四、hash模塊
十五、正則模塊re
一、time模塊,時間的三種格式(重點)
1、time.time --unix元年(1970年1月1日00:00:00)時間到當前時間,一共有多少秒
import time
print(time.time())
>>:1527000352.3488626
#unix元年(1970年1月1日00:00:00)時間到當前時間,一共有多少秒
2、time.strftime --格式化時間,可以自定義時間格式
import time
print(time.strftime("%Y-%m-%d %X"))
>>:格式化的時間字符串:'2018-05-22 22:47:41'
# %Y:年,%m:月,%d:日,%X:當前時間(時:分:秒)的格式,%X==%H:%M:%S
3、struct_time --結構化時間,取得是當前時區的時間
import time
print(time.localtime()) #時間對象(把一個完整的時間拆分成一個個小的部分,方便單獨取值)
>>:time.struct_time(tm_year=2018, tm_mon=5, tm_mday=22, tm_hour=22, tm_min=52, tm_sec=26, tm_wday=1, tm_yday=142, tm_isdst=0)
print(time.localtime().tm_year) #取時間對象內的參數(tm_year)得到對應的值(年)
>>:2018
print(time.localtime().tm_mon) #取時間對象內的參數(tm_mon)得到對應的值(月)
>>:5
print(time.localtime().tm_mday) #取時間對象內的參數(tm_mday)得到對應的值(日)
>>:22
print(time.localtime().tm_hour) #取時間對象內的參數(tm_hour)得到對應的值(時象)
>>:23
4、time.gmtime與struct_time結構一樣,只不過time.gmtime取得時間是 [GMT時區(世界標準時間)的時間對象]
import time
print(time.gmtime())
# time.struct_time(tm_year=2018, tm_mon=10, tm_mday=6, tm_hour=15, tm_min=53, tm_sec=56, tm_wday=5, tm_yday=279, tm_isdst=0)
print(time.gmtime().tm_year)
# 2018
print(time.gmtime().tm_mon)
# 10
print(time.gmtime().tm_mday)
# 6
print(time.gmtime().tm_hour)
# 15
print(time.gmtime().tm_sec)
# 56
1.2、時間之間的轉換關係(瞭解)
圖解:
1)、時間戳 (123123) 轉換成結構化時間time.localtime() :傳入一個數字,單位爲秒,得到的值就是Unix元年加上這個秒數後的日期
import time
print(time.localtime(123123)) #123123秒
>>:time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=18, tm_min=12, tm_sec=3, tm_wday=4, tm_yday=2, tm_isdst=0)
print(time.gmtime(123123)) #123123秒
>>:time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=10, tm_min=12, tm_sec=3, tm_wday=4, tm_yday=2, tm_isdst=0)
2)、把結構化時間 time.localtime() 轉換成時間戳(單位/秒)
import time
print(time.mktime(time.localtime()))
>>:1527002000.0
3)、結構化的時間 time.localtime() 轉換成 年-月-日 的形式
import time
print(time.strftime('%Y-%m-%d',time.localtime()))
# 2018-10-07
4)、把格式化的 年-月-日 時間轉換成結構化時間
import time
print(time.strptime('2017-05-22','%Y-%m-%d'))
>>:time.struct_time(tm_year=2017, tm_mon=5, tm_mday=22, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=142, tm_isdst=-1)
5)、其他時間格式
import time
time.sleep(3) #等待3秒在執行
print(time.asctime(time.localtime())) #linux服務器時間格式(轉換本地時間)
>>:Tue May 22 23:27:21 2018
print(time.ctime(123123)) #時間戳形式
>>:Fri Jan 2 18:12:03 1970
6)、asctime與ctime的區別與使用
圖解:
區別:ctime可以把時間戳轉換成%a %b %d %H %M %S %Y這種格式
asctime可以把結構化時間換成%a %b %d %H %M %S %Y這種格式
例子:
import time
print(time.asctime(time.localtime()))
# Sun Oct 7 00:51:56 2018
print(time.ctime(123123))
# Fri Jan 2 18:12:03 1970
二、時間模塊 datatime
2.1、datatime使用
import datetime
print(datetime.datetime.now()) #打印當前時間
# >>:2018-05-22 23:33:57.233285
print(datetime.datetime.now().replace(year=1999,hour=3)) #把當前時間的"年"替換成了1999年,"小時"替換成了3
# >>:1999-05-23 03:08:38.648744
print(datetime.datetime.fromtimestamp(123123)) #打印時間戳對應的時間(年-月-日)
# >>:1970-01-02 18:12:03
print(datetime.datetime.now() + datetime.timedelta(days=3)) #打印三天後的當前時間
print(datetime.datetime.now() + datetime.timedelta(days=-3)) #打印三天前的當前時間
print(datetime.datetime.now() + datetime.timedelta(weeks=3)) #打印三週後的當前時間
print(datetime.datetime.now() + datetime.timedelta(weeks=-3)) #打印三週前的當前時間
三、隨機模塊random
3.1、隨機模塊random重點掌握
import random
print(random.randint(1,3)) #隨機取1~3之間的任意一個整數
# 1或2或3
print(random.choice([1,'a','b',3])) #在指定的[1,'a','b',3]中隨機取1個值
# 1,'a','b',3這幾個裏面隨機取一個值
3.2、隨機模塊random瞭解知識點
import random
print(random.random()) #默認取得值是0~1之間的小數
# 0.14528372626216834
print(random.randint(1,3)) #隨機取1~3之間的任意一個整數
# 1或2或3
print(random.randrange(1,3)) #由於使用了range(顧頭不顧尾),所以隨機只能取到1或者2
# 1或2
print(random.choice([1,'a','b',3])) #在指定的[1,'a','b',3]中隨機取1個值
# 1,'a','b',3這幾個裏面隨機取一個值
print(random.sample([1,'a','b',3],2)) #在指定的[1,'a','b',3]中隨機取2個值,然後組合成一個列表
# ['a', 'b']
print(random.uniform(1,3)) #取1~3之間隨機的一個小數
# 2.6304200041904804
list=[1,3,5,7,9]
random.shuffle(list) #洗牌,也就是重新將這個列表裏面的值打亂順序
print(list)
# [7, 3, 5, 9, 1]
3.3、補充:chr 將十進制的數字按照ASCII錶轉成字母,而ord 正好相反,把字母轉換成數字
print(chr(65))
# A
print(chr(90))
# Z
print(ord('A'))
# 65
print(ord('Z'))
# 90
3.4、生成隨機驗證碼功能 [數字+大小寫字母+特殊字符]
import random
def make_code(num=5):
res=''
for n in range(num):
s1=str(random.randint(0,9)) # 取一個字符串類型的隨機數字(因爲後面需要用'+'號拼接,所以要用str(random.randint(0,9)))
s2=chr(random.randint(65,90)) # 取一個隨機的大寫字母
s3=s2.lower() # 取一個隨機的小寫字母
s4=random.choice(['!','@','#','$','%','^','&','*']) # 取一個特殊字符
res+=random.choice([s1,s2,s3,s4]) # 將s1,s2,s3,s4字符拼接起來
print(res)
make_code(20)
>>: czzBd&C0z0@y#Y^AaZ@! #最終拿到了一個20位數隨機碼
四、os模塊 -- os模塊是與操作系統交互的一個接口
import os
print(os.getcwd()) #獲取當前工作目錄,即當前python腳本工作的目錄路徑,相當於Linux下的"pwd"
print(os.chdir()) #改變當前腳本工作目錄;相當於shell下cd
print(os.curdir) #返回當前目錄: ('.')
os.pardir #獲取當前目錄的上一個目錄:('..')
os.makedirs('dirname1/dirname2') #遞歸創建目錄,相當於linux下的 "mkdir -p"
os.removedirs('dirname1') #遞歸的刪除目錄
os.mkdir('dirname') #在當前目錄下創建目錄
os.rmdir('dirname') #刪除單級空目錄,若目錄不爲空則無法刪除,報錯;相當於shell中rmdir dirname
os.listdir('.') #列出指定目錄下的所有文件和子目錄,包括隱藏文件,並以列表方式打印
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的大小
4.1、os模塊幾個要記住的用法
1.打印當前目錄下所有的文件,類似 ls
import os
print(os.listdir(r'.')) #打印當前目錄下的所有文件
>>:['test.txt', 'test.xml', 'test.xml.swap', '第七節課.py']
2.使用os.system可以執行系統命令 --不能拿到執行命令後的結果
import os
os.system('ipconfig') #使用os.system執行系統命令,把執行命令後的結果輸出到屏幕
res=os.system('ipconfig') #把命令執行的結果賦值給res,類似linux下的"echo "$?" "
print(res)
# >>:0 #返回"0"表示命令執行成功
# >>:1 #返回"1"表示命令執行失敗
使用os.system執行系統命令,把執行命令後的結果輸出到屏幕,雖然可以通過賦值操作給一個變量值,但是隻能拿到'0'和'1',而不能拿到執行命令後的結果,這裏可以通過(suprocess模塊)實現。
3、打印當前文件的絕對路徑
方式一:
import os
res=os.path.join(
os.path.abspath(__file__), #獲取當前文件名
'..', #獲取上一級目錄".."
'..' #獲取上一級目錄".."
)
print(os.path.normpath(res)) #使用os.path.normpath,得到當前文件的絕路徑(根路徑)
>>:C:\Users\stsud\Desktop\Pycharm文檔
方式二:
import os
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
五、sys模塊
1、sys.argv #命令行參數List,第一個元素是程序本身路徑
2、sys.exit(n) #退出程序,正常退出時exit(0)
3、sys.version #獲取Python解釋程序的版本信息
4、sys.path #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
5、sys.platform #返回操作系統平臺名稱
例子:
import sys
print(sys.argv)
>>:['C:/Users/stsud/Desktop/Pycharm文檔/第七次課/第七節課.py']
sys.exit(0) #退出程序,正常退出時exit(0)
print(sys.version) #查看Python解釋器的版本信息
>>:3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)]
print(sys.path) #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
>>:['C:\\Users\\stsud\\Desktop\\Pycharm文檔\\第七次課', 'C:\\Users\\stsud\\Desktop\\Pycharm文檔', 'C:\\Install Path\\Python3.6\\python36.zip', 'C:\\Install Path\\Python3.6\\DLLs', 'C:\\Install Path\\Python3.6\\lib', 'C:\\Install Path\\Python3.6', 'C:\\Install Path\\Python3.6\\lib\\site-packages', 'C:\\Install Path\\Python3.6\\lib\\site-packages\\pip-10.0.1-py3.6.egg', 'C:\\Install Path\\Pycharm-破解版\\PyCharm 2018.1\\helpers\\pycharm_matplotlib_backend']
print(sys.platform) #返回操作系統平臺名稱
>>:win32
5.1、利用sys模塊打印進度條:基礎進階
#進度條功能:手動麪條版
import sys,time
print('\r[#####]',end='') #"\r"表示每次打印的內容都從第一行開始(相當於第二次打印的內容會覆蓋掉第一次打印的內容)
time.sleep(1)
print('\r[######]',end='') #"\r"表示每次打印的內容都從第一行開始(相當於第二次打印的內容會覆蓋掉第一次打印的內容)
time.sleep(1)
print('\r[#######]',end='') #"\r"表示每次打印的內容都從第一行開始(相當於第二次打印的內容會覆蓋掉第一次打印的內容)
time.sleep(1)
print('\r[############]',end='') #end='' 表示把每一行的換行符替換爲空
[######]
#進度條功能:手動麪條版-升級
import sys,time
print('[%-50s]' %'#') #'[%-50s]'其中"-50"表示左對齊,寬度爲50,%s還是用來傳值的
print('[%-50s]' %'##')
print('[%-50s]' %(int(0.3*50)*'#')) #(int(0.3*50)*'#'),數字與字符相乘==(15*'#')
print('[%-50s]' %(int(1*50)*'#')) #(int(1*50)*'#'),數字與字符相乘==(50*'#')
print('%d%%' %30) #2個%%表示取消%的特殊意義,就只是一個普通的字符"%",那麼%d=30,%%=%,得出30%
print(('[%%-%ss]' %50) %'#######') #('[%%-%ss]' %50)給傳一個值50進去後就會得到[%-50s]
#進度條功能:綜合升級版
import sys,time
def jindutiao(precent,width=50):
print(('\r[%%-%ss]' %width) %(int(precent * width) * '#'),end='')
# print('\r[%%-%ss]' % width) 拿到的值爲:[%-50s]
# %(int(precent * width) * '#') 拿到的值爲:'#'
# 二者合一拿到的爲:('[%-50s]' %'#') == [# ]
total_size=102400 #下載總量
resv_size=0 #接受量爲0
# 通過循環覆蓋的過程來實現進度條增長!
while resv_size < total_size: #接受量小於下載總量時
time.sleep(0.1)
resv_size+=1024 #每次下載1024
precent=resv_size / total_size #已下載量除以下載總量得到一個百分比
jindutiao(precent) #把得到的百分比傳到函數jindutiao裏面
5.2、利用sys模塊打印進度條:完整功能
#進度條功能:綜合完整版
import sys,time
def jindutiao(precent,width=50): #主體函數
if precent>1: #如果百分比大於100%時,把它固定死,不能超過100%
precent=1
show_str=('\r[%%-%ss]' %width) %(int(precent * width) * '#')
# show_str 拿到的值爲:[##################################################] 末尾沒有百分比%
print( '\r%s %d%%' % (show_str,int(precent * 100)),end='' )
# %s用來接收show_str的值
# %d用來接收int(precent * 100)的值,接收的字符類型爲整數
# %%就是一個%號
#################################上面爲主體函數-可套用################################
#測試進度條功能
total_size=102400 #下載總量
resv_size=0 #接受量爲0
while resv_size < total_size: #接受量小於下載總量時
time.sleep(0.1)
resv_size+=1024 #每次下載1024
precent=resv_size / total_size #已下載量除以下載總量得到一個百分比
jindutiao(precent) #把得到的百分比傳到函數jindutiao裏面
六、shutil模塊 --高級的文件、文件夾、壓縮包處理模塊
6.1、將 test.txt 的文件內容拷貝到另一個文件 new.txt 中
import shutil
shutil.copyfileobj(open('test.txt','r'), open('new.txt', 'w'))
原理:將test.txt以"r"只讀的模式讀出文件內容,然後以"w"寫的模式把讀出的文件內容寫到新的new.txt文件中。
6.2、拷貝文件
import shutil
shutil.copyfile('new.txt', 'new2.txt') #目標文件無需存在
6.3、僅拷貝權限。內容、組、用戶均不變
import shutil
shutil.copymode('f1.log', 'f2.log') #目標文件必須存在
6.4、僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags
import shutil
shutil.copystat('f1.log', 'f2.log') #目標文件必須存在
6.5、拷貝文件和權限
import shutil
shutil.copy('f1.log', 'f2.log')
6.6、拷貝文件和狀態信息
import shutil
shutil.copy2('f1.log', 'f2.log')
6.7、遞歸的去拷貝文件夾
import shutil
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除
6.8、遞歸的去移動文件,它類似mv命令,其實就是重命名。
import shutil
shutil.move('folder1', 'folder3')
6.9、shutil.make_archive 打包文件
import shutil
ret = shutil.make_archive("test_bak", 'gztar', root_dir=r'C:\Users\stsud\Desktop\Pycharm文檔\第七次課')
註釋:
test_bak 打包後命名爲"test_bak.tar.gz"
gztar 以tar的方式打包文件
root_dir 被打包的文件
6.10、tarfile 解壓文件
import tarfile
f=tarfile.open('test_bak.tar.gz','r')
f.extractall(r'C:\Users\stsud\Desktop\Pycharm文檔\第八節課')
f.close()
註釋:
tarfile.open('test_bak.tar.gz','r') 以'r'只讀模式打開test_bak.tar.gz文件
f.extractall(r'C:\Users\stsud\Desktop\Pycharm文檔\第八節課') 文件解壓後存放的目錄
f.close() 文件打開後需要被關閉
shutil 對壓縮包的處理是調用 zipfile 和 tarfile 兩個模塊來進行的,詳細:
6.10.1、zipfile 模塊壓縮與解壓
import tarfile
打包
t=tarfile.open('test.tar.gz','w')
t.add('test.txt')
t.close()
註釋:
test.tar.gz 打包後的文件名,以'w'的方式打開
t.add('test.txt') 打包的文件名
t.close() 打包完畢後關閉文件
解壓
t=tarfile.open('test.tar','r')
t.extractall(r'C:\Users\stsud\Desktop\Pycharm_Document\第七次課')
t.close()
註釋:
data.tar.gz 需要被解壓的文件,以只讀模式打開
f.extractall 指定解壓的目錄
f.close() 解壓完畢後關閉
七、shevle 模塊 ---只支持Python格式的數據類型
7.1、把內容寫到文件裏面
import shelve
f=shelve.open(r'shelve.txt') #打開一個文件並寫入內容,並存在磁盤裏面
f['a']={'age':18,'sex':'male'}
f['b']={'age':38,'sex':'famale'}
f.close()
7.2、文件寫好後,取值的話,按照正常的方式取值就可以了
import shelve
f=shelve.open(r'shelve.txt') #打開一個文件並寫入內容,並存在磁盤裏面
f['a']={'age':18,'sex':'male'}
f['b']={'age':38,'sex':'famale'}
print(f['a']) #取出'a'的所有值
>>:{'age': 18, 'sex': 'male'}
print(f['b'])
>>:{'age': 38, 'sex': 'famale'}
print(f['b']['age']) #取出'a'裏面的'age'的值
>>:38
print(f['b']['sex'])
>>:famale
f.close()
7.3、修改文件內容
import shelve
f=shelve.open(r'shelve.txt',writeback='True') #要加writeback='True',表示寫回
f['a']={'age':18,'sex':'male'}
f['b']={'age':38,'sex':'famale'}
f['a']['age']=19 #修改文件內內容'age'爲19
print(f['a']['age'])
>>:19
f.close()
八、suprocess 模塊 ---可執行系統命令的模塊(或者在cmd命令中運行的程序)
8.1、執行正確的命令之後的返回值給管道,通過stdout=subprocess.PIPE獲取
import subprocess
obj=subprocess.Popen(
'ipconfig', # 'ipconfig' 要執行的命令,輸入的命令必須是字符串形式。
shell=True, # shell=True 調用'命令解釋器'來執行'ipconfig'這個命令。
stdout=subprocess.PIPE, # stdout=subprocess.PIPE 即管道(命令執行後結構給到管道),stdout表示輸入正確的命令得到的返回值。
stderr=subprocess.PIPE, # stderr=subprocess.PIPE # stderr表示輸入錯誤的命令得到的返回值。
)
stdout=obj.stdout.read() # 把管道內的值(執行命令後得到的值)賦值給stdout
print(stdout.decode('gbk')) # 不加字符集得到的是二進制形式的返回值,這裏要使用操作系統所使用的字符集('gbk')
>>: 映像名稱 PID 會話名 會話# 內存使用
>>: ========================= ======== ================ =========== ============
>>: System Idle Process 0 Services 0 8 K
>>: System 4 Services 0 24 K
>>: Registry 120 Services 0 13,280 K
8.2、輸入錯誤的命令之後的返回值給管道,通過stderr=subprocess.PIPE獲取
import subprocess
obj=subprocess.Popen(
'taskliasdasdst', # 'taskliasdasdst' 要執行的命令,輸入的命令必須是字符串形式。
shell=True, # shell=True 需要調用命令解釋器來幫我執行'tasklist'這個命令
stdout=subprocess.PIPE, # stdout=subprocess.PIPE 即管道(命令執行後結構給到管道),stdout表示輸入正確的命令得到的返回值
stderr=subprocess.PIPE, # stderr=subprocess.PIPE # stderr表示輸入錯誤的命令得到的返回值
)
stderr=obj.stderr.read() # 把管道內的值(執行命令後得到的值)賦值給stdout
print(stderr.decode('gbk')) # 不加字符集得到的是二進制形式的返回值,這裏要使用操作系統所使用的字符集('gbk')
>>: 'taskliasdasdst' 不是內部或外部命令,也不是可運行的程序
>>: 或批處理文件。
8.3、suprocess(翻譯過來:子進程)不單單只是一個執行命令的模塊,在程序運行中,會先運行主進程,主進程可以生產一個子進程,在主進程運行的同時子進程也在運行(相當於併發執行,可提高效率,節省時間)
以下爲suprocess模塊的正常使用方法。
import subprocess
obj=subprocess.Popen( #執行命令的過程
'tasklist',
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
stdout=obj.stdout.read() #拿到執行命令得到的結果
print(stdout.decode('gbk'))
九、paramiko模塊 簡單執行遠程命令的用法
9.1、基於IP和端口連接的用法
#paramiko模塊的簡單遠程執行命令:用法一
import paramiko
# 創建SSH對象--(實例化)
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機 (連接SSH時,輸入Yes/No)--固定用法
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器--指定IP,端口,用戶名和密碼
ssh.connect(hostname='192.168.200.142', port=22, username='root', password='123456')
# 執行命令 --執行"df -h"命令
stdin, stdout, stderr = ssh.exec_command('df -h') #把執行命令得到的結果放在管道里面
#stdin 標準輸入
#stdout 標準輸出
#stderr 標準錯誤
# 獲取命令結果--獲取正確的結果
result = stdout.read()
print(result.decode('utf-8')) # windows系統爲gbk編碼,linux系統爲utf-8編碼
# 關閉連接
ssh.close()
# 得到的值:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 8.6G 1.5G 6.7G 19% /
tmpfs 497M 0 497M 0% /dev/shm
/dev/sda1 190M 35M 146M 19% /boot
paramiko模塊的簡單遠程執行命令:用法二
import paramiko
transport = paramiko.Transport(('192.168.200.142', 22))
transport.connect(username='root', password='123456')
ssh = paramiko.SSHClient()
ssh._transport = transport
stdin, stdout, stderr = ssh.exec_command('df -h')
res=stdout.read()
print(res.decode('utf-8'))
transport.close()
# 得到的值:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 8.6G 1.5G 6.7G 19% /
tmpfs 497M 0 497M 0% /dev/shm
/dev/sda1 190M 35M 146M 19% /boot
9.2、基於ssh-key祕鑰連接的用法(未測試)
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')
# 創建SSH對象
ssh = paramiko.SSHClient()
# 允許連接不在know_hosts文件中的主機
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 連接服務器
ssh.connect(hostname='120.92.84.249', port=22, username='root', pkey=private_key)
# 執行命令
stdin, stdout, stderr = ssh.exec_command('df')
# 獲取命令結果
result = stdout.read()
print(result.decode('utf-8'))
# 關閉連接
ssh.close()
9.3、SFTPClient--用於連接遠程服務器並執行上傳下載
1.基於用戶名密碼上傳下載
import paramiko
transport = paramiko.Transport(('192.168.200.142', 22))
transport.connect(username='root', password='123456')
sftp = paramiko.SFTPClient.from_transport(transport)
# 將本地的"C:\MLBB\部署記錄\2,3,5大區分區部署.txt"文件,上傳至服務器並重命名"/root/szq_test.txt" --這裏不單單指定上傳的目錄,必須指定上傳後的文件名
sftp.put(r'C:\MLBB\部署記錄\2,3,5大區分區部署.txt', '/root/szq_test.txt')
# 將服務器的/etc/passwd文件,下載到本地並重命名"D:\passwd" --同樣,下載也是不單單指定下載的目錄,必須指定下載後的文件名
sftp.get('/etc/passwd', r'D:\passwd')
transport.close()
2.基於公鑰密鑰上傳下載(未測試)
import paramiko
private_key = paramiko.RSAKey.from_private_key_file('/tmp/id_rsa')
transport = paramiko.Transport(('120.92.84.249', 22))
transport.connect(username='root', pkey=private_key )
sftp = paramiko.SFTPClient.from_transport(transport)
# 將location.py 上傳至服務器 /tmp/test.py
sftp.put('/tmp/id_rsa', '/tmp/a.txt')
# 將remove_path 下載到本地 local_path
sftp.get('remove_path', 'local_path')
transport.close()
十、configparser模塊 --解析配置文件用的模塊
配置文件 my.ini 內容:
[egon]
pwd=123
age=18
salary=3.1
is_beautiful=True
[alex]
pwd=3714
age=38
salary=3.2
使用例子:
import configparser
config=configparser.ConfigParser()
config.read('my.ini')
print(config.sections())
# ['egon', 'alex'] # 取配置文件的文件內容的標題部分
print(config.options('egon'))
# ['pwd', 'age', 'salary', 'is_beautiful'] # 取配置文件的文件內容標題對應的內容部分
print(config.getint('egon','age')) # 使用getint相當於是給取到的值的類型做了int處理,即int(value)
# 18 # 取配置文件的文件內容標題對應的內容部分(key)對應的值(整數)
print(config.getfloat('egon','salary'))
# 3.1 # 取配置文件的文件內容標題對應的內容部分(key)對應的值(小數)
print(config.getboolean('egon','is_beautiful'))
# True # 取配置文件的文件內容標題對應的內容部分(key)對應的值(布爾類型)
十二、logging模塊
1、日誌的級別,默認日誌級別爲"warning"級別,默認打印到終端。
五: critical 對應數字: 50
四: error 對應數字: 40
三: warning 對應數字: 30
二: info 對應數字:20
一: debug 對應數字:10
import logging
logging.debug('debug級別')
logging.info('info級別')
logging.warning('warning級別')
logging.error('error級別')
logging.critical('critical級別')
WARNING:root:warning級別
ERROR:root:error級別
CRITICAL:root:critical級別
註釋:
WARNING:日誌級別
:(分隔符)
root:日誌名
warning級別:日誌的信息
2、爲logging模塊指定全局配置,針對所有logger有效,控制日誌信息打印到文件中
可在logging.basicConfig()函數中通過具體參數來更改logging模塊默認行爲,
1、可用參數有:
filename :用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode :文件打開方式,在指定了filename時使用這個參數,默認值爲“a”還可指定爲“w”。
format :指定handler使用的日誌顯示格式。
datefmt :指定日期時間格式。
level :設置rootlogger的日誌級別
stream :用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認爲
sys.stderr :若同時列出了filename和stream兩個參數,則stream參數會被忽略。
1.1、format(格式)參數:
%(name)s :Logger的名字,並非用戶名,詳細查看
%(levelno)s :數字形式的日誌級別
%(levelname)s :文本形式的日誌級別
%(pathname)s :調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s :調用日誌輸出函數的模塊的文件名
%(module)s :調用日誌輸出函數的模塊名
%(funcName)s :調用日誌輸出函數的函數名
%(lineno)d :調用日誌輸出函數的語句所在的代碼行
%(created)f :當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d:輸出日誌信息時的,自Logger創建以 來的毫秒數
%(asctime)s :字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒
%(thread)d :線程ID。可能沒有
%(threadName)s :線程名。可能沒有
%(process)d :進程ID。可能沒有
%(message)s :用戶輸出的消息
3、如何使用 --簡單瞭解用法,右鍵運行後,日誌信息將會被輸入到當前目錄下的access.log文件裏面
import logging
logging.basicConfig(
filename='access.log', #指定日誌輸出到指定文件,默認路徑爲當前路徑
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', #format格式的參數,-號爲分隔符(可自定義)
datefmt='%Y-%m-%d %H:%M:%S %p', #專門用來定製日誌的時間格式
level=10 #日誌級別
)
logging.debug('debug級別')
logging.info('info級別')
logging.warning('warning級別')
logging.error('error級別')
logging.critical('critical級別')
4、logging模塊可以分成四類對象
logging對象 作用:產生日誌
handler對象 作用:控制日誌的去向(日誌信息輸出到哪裏),1日誌信息輸出到文件,2日誌信息輸出到終端。
formatter對象 作用:定製日誌的格式
filter對象 作用:過濾日誌(不常用)
圖解:
4.1、基於logging模塊的四類對象,對logging模塊的簡單用法:
import logging
#一、 logging對象 作用:產生日誌
logger1=logging.getLogger('銀行相關業務') #日誌名,區分業務類型
#二、 handler對象 作用:控制日誌的去向(日誌信息輸出到哪裏),1日誌信息輸出到文件,2日誌信息輸出到終端。
fh1=logging.FileHandler('a1.log',encoding='utf-8')
fh2=logging.FileHandler('a2.log',encoding='utf-8')
ch=logging.StreamHandler() #StreamHandler表示終端
#一+二、 建立logger對象與handler對象的綁定關係
logger1.addHandler(fh1)
logger1.addHandler(fh2)
logger1.addHandler(ch)
#三、 formatter對象 作用:定製日誌的格式
formatter1=logging.Formatter(
fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S %p'
)
formatter2=logging.Formatter(
fmt='%(asctime)s ==> %(message)s',
)
#二+三、 爲handler對象綁定日誌格式
fh1.setFormatter(formatter1)
fh2.setFormatter(formatter2)
ch.setFormatter(formatter2)
#四、 設置日誌級別,兩層關卡(第一層:logger對象,第二層:handler對象),只有兩層都放行,最終日誌纔會產生
logger1.setLevel(10)
fh1.setLevel(10)
fh2.setLevel(10)
ch.setLevel(10)
#五、 調用Logging對象產生日誌
logger1.debug('這是一條debug日誌')
4.2、生產中日誌模塊及格式的正確用法(setting.py與use.py在同一目錄)
1、logging配置,配置文件名setting.py
import os
BASE_DIR=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 定義日誌文件的保存路徑
logfile_path=os.path.join(BASE_DIR,'log','access.log') #log:存在日誌的目錄,access.log:文件名
boss_logfile_path=os.path.join(BASE_DIR,'log','boss.log')
# 定義日誌格式
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 = '[%(asctime)s] %(message)s'
# log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': standard_format
},
'simple': {
'format': simple_format
},
'id_simple': {
'format': id_simple_format
}
},
'filters': {},
'handlers': {
#打印到終端的日誌 -- 實際中是不需要打印到終端的
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到終端
'formatter': 'simple'
},
#打印到文件的日誌,
'default': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'standard',
'filename': logfile_path, # 日誌文件
'encoding': 'utf-8', # 日誌文件的編碼,再也不用擔心中文log亂碼了
},
#打印給boss的日誌 -- 單獨給某個用戶或者自定義日誌的級別
'boss': {
'level': 'ERROR',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'id_simple',
'filename': boss_logfile_path, # 日誌文件
'encoding': 'utf-8', # 日誌文件的編碼,再也不用擔心中文log亂碼了
},
},
'loggers': {
'': { #這裏的key爲空
'handlers': ['default', 'console', 'boss'],
'level': 'DEBUG',
'propagate': False,
},
},
}
2、使用,文件名use.py
import logging.config
from setting import LOGGING_DIC
logging.config.dictConfig(LOGGING_DIC) # 導入上面定義的logging配置
logger=logging.getLogger('ATM') #
logger.error('錯誤')
十三、序列化模塊 json&pickle模塊
13.1、什麼是序列化?
序列化:把內存中的數據轉化成一種中間格式(json/pickle格式),然後存放到硬盤,永久保存。
反序列化:從文件中讀出(json/pickle格式),然後反解成python的數據類型。
13.2、爲什麼要序列化?
1.數據結構持久化
2.跨平臺數據交互
13.3、如何序列化,反序列化?
1、json
缺點:只能支持部分Python的數據類型
優點:所有的語言都支持json格式
應用:如果需要考慮跨平臺性,則需要用json格式
JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應如下:
一、 json序列化例子: dumps與loads
dumps: 把一個字典轉換成json格式的字符串 把字典轉換爲json的字符串
loads: 把json格式的字符串反解成字典 把json的字符串轉換爲字典
import json
dic={'name':'sudada','age':18}
#序列化
res=json.dumps(dic) #強調,json格式不識別單引號
with open('user.json','w',encoding='utf-8')as f:
f.write(res)
#反序列化
with open('user.json','r',encoding='utf-8')as f:
res=f.read()
dic=json.loads(res)
print(dic)
>>: {'name': 'sudada', 'age': 18}
二、 json序列化例子: dump與load
dump:把一個字典序列化到文件裏面
load:直接把文件內容讀出來,然後反解成字典
import json
dic={'name':'sudada','age':18}
# 開始序列化 json.dump(dic,f)
with open('user2.json','w',encoding='utf-8')as f:
json.dump(dic,f) #dic爲要序列化的對象,f爲打開的文件
# 反序列化 json.load(f)
with open('user2.json','r',encoding='utf-8')as f:
dic=json.load(f)
print(dic)
{'name': 'sudada', 'age': 18}
JSON序列化中文時出現亂碼(ascii)的問題
import json
dic={'name':'蘇大大'}
print(json.dumps(dic)) # 這裏打印的不是中文,而是一串ascii碼:{"name": "\u82cf\u5927\u5927"}
# 設置ensure_ascii=False即可將ascii碼轉換爲中文
print(json.dumps(dic,ensure_ascii=False)) # {"name": "蘇大大"}
2、pickle
缺點:只有Python支持pickle格式
優點:pickle能夠支持所有的Python數據類型
應用:如果不需要考慮跨平臺性,則需要用pickle格式
一、pickle序列化例子 dumps與loads
dumps: 把一個字典轉換成pickle格式的字符串
loads: 把pickle格式的字符串反解成字典
import pickle
dic={'name':'sudada','age':18}
# 序列化
res=pickle.dumps(dic)
with open('user3.pkl','wb')as f:
f.write(res)
#反序列化
with open('user3.pkl','rb')as f:
res=f.read()
dic=pickle.loads(res)
print(dic)
{'name': 'sudada', 'age': 18}
二、pickle序列化例子 dump與load
dump:把一個字典序列化到文件裏面
load:直接把文件內容讀出來,然後反解成字典
import pickle
dic={'name':'sudada','age':18}
#序列化
with open('user4.pkl','wb')as f:
pickle.dump(dic,f)
#反序列化
with open('user4.pkl','rb')as f:
res=pickle.load(f)
print(res)
{'name': 'sudada', 'age': 18}
十四、hash模塊
14.1、什麼是hash?
hash是一種算法,該算法是用來校驗文件內容
14.2、hash算法的三大特點
1、只要校驗的文本內容一樣,那得到的hash值也一樣。
2、只要使用hash算法固定,無論校驗的內容有多大,得到的hash值的長度都是固定的
3、hash值不可逆(無法通過hash值反解成明文),將明文轉換成密文進行傳輸(把明文密碼變成密文傳輸)
14.3、如何使用hash?
簡單瞭解如何使用:
1、建造一個hash工廠
2、update接收的數據類型都必須是bytes類型
3、最後使用m.hexdigest()得到hash值
import hashlib
m=hashlib.md5() # 建造一個hash工廠
m.update(b'hello') # update接收的數據類型都必須是bytes類型
m.update(b'world')
m.update(b'sudaa')
# hash的值合起來爲: b'helloworldsudaa'
print(m.hexdigest()) # 最後使用m.hexdigest()得到hash值
# f10c2a3d06ba5d07becde825224d97b1
14.4、對一個大文件(a.mp4)做hash --使用方式一
方式一:打開文件後,一行行讀取內容,最後使用m.hexdigest()拿到hash值
import hashlib
m=hashlib.md5()
with open('a.mp4','rb')as f:
for line in f:
m.update(line)
print(m.hexdigest())
# 9be361df7bfdd8637423d81bd7bce0ef
方式二:直接讀取所有的文件內容,使用m.hexdigest()拿到hash值 (二者得到的hash值是一樣的)
import hashlib
m=hashlib.md5()
with open('a.mp4','rb')as f:
m.update(f.read())
print(m.hexdigest())
# 9be361df7bfdd8637423d81bd7bce0ef
14.5、將明文密碼加密 --爲了防止通過撞庫的破解方式,需要給密碼加鹽
import hashlib
passwd='sudada123456'
m=hashlib.md5()
m.update('天王蓋地虎'.encode('utf-8'))
m.update(passwd.encode('utf-8'))
m.update('寶塔鎮河妖'.encode('utf-8'))
res=m.hexdigest()
print(res)
# 2a1d46c970520ff47261c1a0b0a58f04
十五、正則模塊re
1、什麼是正則?
正則就是用一些具有特殊含義的符號組合到一起(稱爲正則表達式)來描述字符或者字符串的方法。(在Python中)它內嵌在Python中,並通過 re 模塊實現。
2、常用匹配模式(元字符)
3、正則模塊常用實踐操作例子
1、' \w ' 匹配字母數字及下劃線
import re
# '\w' 匹配的規則(匹配哪些字符)
# 'ab_123 4_c\n\t' 對哪些內容做匹配
res=re.findall('\w','ab_123 4_c\n\t')
print(res)
# 拿到的數據放在一個列表裏面。
['a', 'b', '_', '1', '2', '3', '4', '_', 'c']
2、'\W' 匹配非字母數字及下劃線
import re
print(re.findall('\W','ab_123 4_c\n\t'))
# [' ', '\n', '\t']
3、'\s' 匹配任意空白字符,包含[\t,\n,\r,\f],只要有'\t,\n,\r,\f'都會被匹配到。
import re
print(re.findall('\s','ab_123 4_c\n\t'))
# [' ', ' ', '\n', '\t']
4、'\s\s' 同時匹配兩個任意空白字符
import re
print(re.findall('\s\s','ab_123 4_c\n\t'))
# [' ', '\n\t']
5、'\S' 匹配任意非空字符
import re
print(re.findall('\S','ab_123 4_c\n\t'))
# ['a', 'b', '_', '1', '2', '3', '4', '_', 'c']
6、'\S\S\S'匹配3個連續的非空字符
import re
print(re.findall('\S\S\S','ab_123 4_c\n\t'))
# ['ab_', '123', '4_c']
7、'^aaa' 匹配以aaa開頭的內容
import re
# print(re.findall('^aaa','aaa name is aaa,aaa is sb'))
# ['aaa']
8、'aaa$' 匹配以aaa結尾的內容
import re
print(re.findall('sb$','aaa name is aaa,aaa is sb'))
# ['sb']
9、'\n' '\t' 分別只匹配'\n'和'\t' 的字符
import re
print(re.findall('\n','ab_123 4_c\n\t'))
# ['\n']
print(re.findall('\t','ab_123 4_c\n\t'))
# ['\t']
重複匹配字符: . ? * + {m,n}
10、' . ' 匹配任意字符,除了換行符(\n),怎樣才能匹配到換行符(\n)呢,需要用到re.DOTALL
import re
# 重複匹配: . ? * + {m,n}
print(re.findall('a.c','123 123a1c xixi a2c a\nc aaaaaac a-c a*c',re.DOTALL))
# ['a1c', 'a2c', 'a\nc', 'aac', 'a-c', 'a*c']
11、 ' ? ' 表示左側的字符出現0個或者1個
import re
print(re.findall('ab?','a ab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'ab', 'ab', 'ab', 'a', 'a']
#ab?的匹配規則是:以a開頭,b結尾的(不包含中間的值),或者只有a開頭的。
12、' * ' 表示左側的字符出現0個或者無數個
import re
print(re.findall('ab*','a ab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'abb', 'abbbb', 'abbbbbbbb', 'a', 'a']
#ab*的匹配規則是:以a開頭,b結尾的(包含中間所有的),或者只有a開頭的。
13、' + ' 表示左側的字符有1個或者無數個,並且左側的字符都必須存在
import re
print(re.findall('ab+','a ab abb abbbb abbbbbbbb bbbbba123a'))
# ['ab', 'abb', 'abbbb', 'abbbbbbbb']
#ab+的匹配規則是:ab必須都存在。
14、' {m+n} ' 表示左側的字符有m到n個
import re
print(re.findall('ab{2,4}','a ab abb abbbb abbbbbbbb bbbbba123a'))
# ['abb', 'abbbb', 'abbbb']
#ab{2,4}的匹配規則是:以a開頭,b結尾,其中{2,4}只針對b生效,也就是說:最少取2個b,最多取4個b。
例子2:
print(re.findall('a{2,4}b','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['aab', 'aaaab']
#a{2,4}b的匹配規則是:以a開頭,b結尾,其中{2,4}只針對a生效,也就是說:最少取2個a,最多取4個a。
例子3:
print(re.findall('ab{2,}','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['abb', 'abbbb', 'abbbbbbbb']
#ab{2,}b的匹配規則是:以a開頭,b結尾,其中{2,}表示:b最少取2個,最多可以取無數個。
15、用{m,n}的形式可以把 ? * + 都給替代了
import re
例子一:用{0,1}替代? ab? == ab{0,1}
print(re.findall('ab?','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'a', 'a', 'a', 'a', 'ab', 'ab', 'ab', 'ab', 'a', 'a']
print(re.findall('ab{0,1}','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'a', 'a', 'a', 'a', 'ab', 'ab', 'ab', 'ab', 'a', 'a']
例子二:用{0,}替代* ab* == ab{0,}
print(re.findall('ab*','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'a', 'a', 'a', 'a', 'ab', 'abb', 'abbbb', 'abbbbbbbb', 'a', 'a']
print(re.findall('ab{0,}','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['a', 'ab', 'a', 'a', 'a', 'a', 'ab', 'abb', 'abbbb', 'abbbbbbbb', 'a', 'a']
例子三:用{1,}替代+ ab+ == ab{1,}
print(re.findall('ab+','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['ab', 'ab', 'abb', 'abbbb', 'abbbbbbbb']
print(re.findall('ab{1,}','aab aaaaab abb abbbb abbbbbbbb bbbbba123a'))
# ['ab', 'ab', 'abb', 'abbbb', 'abbbbbbbb']
16、' .* ' 貪婪匹配,與 ' .*? ' 非貪婪匹配
import re
print(re.findall('a.*c','a123123123123123123c123123123123123c'))
# ['a123123123123123123c123123123123123c']
#a.*c 的匹配規則是:以a開頭,b結尾,匹配中間的所有內容,無論是否有隔斷。
print(re.findall('a.*?c','a123123123123123123c123123123123123c'))
# ['a123123123123123123c']
#a.*?c 的匹配規則是:以a開頭,b結尾,匹配中間的所有內容,只取匹配到的第一段。
17、分組 () 與或 |
import re
print(re.findall('compan(ies|y)','companies and company'))
# ['ies', 'y']
#compan(ies|y)默認只取組內的結果,也就是隻能取到ies或者y。
print(re.findall('compan(?:ies|y)','companies and company'))
# ['companies', 'company']
#compan(?:ies|y)就是把匹配到內容都取出來,而不是隻保留組內的結果
18、取字符串裏面的URL,使用 ' (.*?) '
import re
print(re.findall('a href="(.*?)"',
'<a href="https://www.baidu.com"><a href="http://www.baidu.com">'))
# ['https://www.baidu.com', 'http://www.baidu.com']
19、[ ] 匹配一個字符,但是這個字符需要在寫 [ ] 內
import re
print(re.findall('a[+]c','abc a-c a+c a*c a1c a2c')) #單個使用
# ['a+c']
print(re.findall('a[+0-9]c','abc a-c a+c a*c a1c a2c')) #組合使用不需要分隔符
# ['a+c', 'a1c', 'a2c']
#在[]內'-'表示的是範圍,如果要是有'-',那麼就要使用轉譯\-
#0-9表示:匹配任意數字
#a-z表示:匹配任意小寫字母
#A-Z表示:匹配任意大寫字母
在[ ] 內轉譯字符的方法:
import re
print(re.findall('a[\+\-\*\/]c','abc a-c a+c a*c a/c a2c'))
# ['a-c', 'a+c', 'a*c', 'a/c']
在[ ] 內匹配多個數字的寫法:[0-9][0-9]表示匹配2爲數字,[0-9]*表示匹配任意數字,無論多少位。
import re
print(re.findall('a[0-9][0-9]c','a11c a-c a+c a*c a1c a2c'))
# ['a11c']
print(re.findall('a[0-9]*c','a23111c a-c a+c a*c a1c a2c'))
# ['a23111c', 'a1c', 'a2c']
20、re.search 可以判斷匹配的值是否存在,若存在返回一個對象,若不存在則返回None
import re
print(re.search('e','a b c d e f g'))
# <_sre.SRE_Match object; span=(8, 9), match='e'>
#如果能夠匹配到'e',那麼就返回一個對象
print(re.search('aa','a b c d e f g'))
# None
#如果不能夠匹配到'e',那麼就返回None
如果想要re.search向re.findall那樣匹配某一個值的話,需要在re.search後面加一個.group
import re
print(re.search('e','a b c d e f g').group())
# e
21、re.match('a') 等同於re.search('^a')
import re
print(re.search('^a','a b c d e f g').group())
print(re.match('a','a b c d e f g').group())
# a
# a
22、re.sub 替換: re.sub('Today','Yesterday') 把Today替換成Yesterday
import re
print(re.sub('Today','Yesterday','Today is Monday'))
'Today' # 替換的值
'Yesterday' # 被替換的對象
'Today is Monday' # 對什麼做替換
>>: Yesterday is Monday