python第七章_python 第七章 模块
模塊
一個py文件就是一個模塊
模塊一共三種:1.python標準庫 2.第三方模塊 3.應用程序自定義模塊
import:1.執行對應文件 2.引入變量名
if__name__="__main__": #1.用于被調用文件測試 2.防止主程序被調用
time模塊 常用命令
時間模塊
1 importtime2 #時間戳:
3 print(time.tiem())4
5 #結構化時間(當地):
6 t =time.localtime(time.tiem())7 print(t)8
9 #結構化時間(世界標準):
10 t =time.gmtime(time.time())11 print(t)12
13 #需要把時間戳轉換成結構化時間
14
15 #將結構化時間轉換成時間戳:
16 print(time.mktime(time.localtime()))17
18 #將結構化時間轉換成字符串時間:
19 print(time.strftime("%Y-%m-%d %X",time.localtime()))20 %Y年 %m月 %d日 %X時分秒21
22 #將字符串時間轉換成結構化時間:
23 print(time.strptime("2018:8:26:19:58:43","%Y:%m:%d:%X"))24
25 #將一個時間戳轉換成固定的字符串時間:
26 print(time.ctime())27
28 #將結構化時間轉換成固定的字符串時間:
29 print(time.asctime())30
31 #推遲指定的時間運行,單位為秒:
32 time.sleep()33
34 #可以直觀顯示字符串時間:
35 importdatetime36 print(datetime.datetime.now())
random模塊 常用命令
生成隨機數
1 importrandom2
3 #用于生成一個0到1的隨機浮點數
4 print(random.random())5
6 #用于生成一個指定范圍內的整數:
7 random.randint(a,b)8 print(random.randint(1,3))9
10 #從指定范圍內,按指定基數遞增的集合中 獲取一個隨機數:
11 random.randrange([start], stop[, step])12 print(random.randrange(10,30,2))13 random.randrange(10, 30, 2),結果相當于從[10, 12, 14, 16, ... 26, 28]序列中獲取一個隨機數14
15 #從序列中獲取一個隨機元素,參數sequence表示一個有序類型,list, tuple, #字符串都屬于sequence:
16 random.choice(sequence)17 print(random.choice([11,22,33]))18
19 #從指定序列中隨機獲取指定長度的片斷并隨機排列:
20 random.sample(sequence, k)21 print(random.samplc([11,22,33,44,55],2))22
23 #用于生成一個指定范圍內的隨機符點數:
24 random.uniform(a,b)25 print(random.uniform(1,4))26
27 #用于將一個列表中的元素打亂,即將列表內的元素隨機排列:
28 ret =[1,2,3,4,5]29 random.shuffle(ret)30 print(ret)
os模塊 常用命令
os模塊就是對操作系統進行操作
1 importos2
3 #getcwd() 獲取當前工作目錄(當前工作目錄默認都是當前文件所在的文件夾)
4 print(os.getcwd())5
6 #chdir()改變當前工作目錄
7 os.chdir('/home/sy')8 print(os.getcwd())9
10 open('02.txt','w')11 #操作時如果書寫完整的路徑則不需要考慮默認工作目錄的問題,按照實際書寫路徑操作
12 open('/home/sy/下載/02.txt','w')13
14 #listdir() 獲取指定文件夾中所有內容的名稱列表
15 result = os.listdir('/home/sy')16 print(result)17
18 #mkdir() 創建文件夾
19 os.mkdir('girls')20 os.mkdir('boys',0o777)21
22 #makedirs() 遞歸創建文件夾
23 os.makedirs('/home/sy/a/b/c/d')24
25 #rmdir() 刪除空目錄
26 os.rmdir('girls')27
28 #removedirs 遞歸刪除文件夾 必須都是空目錄
29 os.removedirs('/home/sy/a/b/c/d')30
31 #remove 刪除一個文件
32 os.remove()33
34 #rename() 文件或文件夾重命名
35 os.rename('/home/sy/a','/home/sy/alibaba'
36 os.rename('02.txt','002.txt')37
38 #stat() 獲取文件或者文件夾的信息
39 result = os.stat('/home/sy/PycharmProject/Python3/10.27/01.py)
40 print(result)41
42 #system() 執行系統命令(危險函數)
43 result = os.system('ls -al') #獲取隱藏文件
44 print(result)45
46 #環境變量
47 """環境變量就是一些命令的集合48 操作系統的環境變量就是操作系統在執行系統命令時搜索命令的目錄的集合"""
49
50 #getenv() 獲取系統的環境變量
51 result = os.getenv('PATH')52 print(result.split(':'))53
54 #putenv() 將一個目錄添加到環境變量中(臨時增加僅對當前腳本有效)
55 #os.putenv('PATH','/home/sy/下載')
56 #os.system('syls')
57
58 #exit() 退出終端的命令
59
60 #os模塊中的常用值
61 #curdir 表示當前文件夾 .表示當前文件夾 一般情況下可以省略
62 print(os.curdir)63
64 #pardir 表示上一層文件夾 ..表示上一層文件夾 不可省略!
65 print(os.pardir)66
67 #os.mkdir('../../../man')#相對路徑 從當前目錄開始查找
68 #os.mkdir('/home/sy/man1')#絕對路徑 從根目錄開始查找
69
70 #name 獲取代表操作系統的名稱字符串
71 print(os.name) #posix -> linux或者unix系統 nt -> window系統
72
73 #sep 獲取系統路徑間隔符號 window ->\ linux ->/
74 print(os.sep)75
76 #extsep 獲取文件名稱和后綴之間的間隔符號 window & linux -> .
77 print(os.extsep)78
79 #linesep 獲取操作系統的換行符號 window -> \r\n linux/unix -> \n
80 print(repr(os.linesep))81
82 #導入os模塊
83 importos84 #以下內容都是os.path子模塊中的內容
85
86 #abspath() 將相對路徑轉化為絕對路徑
87 path = './boys'#相對
88 result =os.path.abspath(path)89 print(result)90
91 #dirname() 獲取完整路徑當中的目錄部分 & basename()獲取完整路徑當中的主體部分
92 path = '/home/sy/boys'
93 result =os.path.dirname(path)94 print(result)95
96 result =os.path.basename(path)97 print(result)98
99 #split() 將一個完整的路徑切割成目錄部分和主體部分
100 path = '/home/sy/boys'
101 result =os.path.split(path)102 print(result)103
104 #join() 將2個路徑合并成一個
105 var1 = '/home/sy'
106 var2 = '000.py'
107 result =os.path.join(var1,var2)108 print(result)109
110 #splitext() 將一個路徑切割成文件后綴和其他兩個部分,主要用于獲取文件的后綴
111 path = '/home/sy/000.py'
112 result =os.path.splitext(path)113 print(result)114
115 #getsize() 獲取文件的大小
116 #path = '/home/sy/000.py'
117 #result = os.path.getsize(path)
118 #print(result)
119
120 #isfile() 檢測是否是文件
121 path = '/home/sy/000.py'
122 result =os.path.isfile(path)123 print(result)124
125 #isdir() 檢測是否是文件夾
126 result =os.path.isdir(path)127 print(result)128
129 #islink() 檢測是否是鏈接
130 path = '/initrd.img.old'
131 result =os.path.islink(path)132 print(result)133
134 #getctime() 獲取文件的創建時間 get create time
135 #getmtime() 獲取文件的修改時間 get modify time
136 #getatime() 獲取文件的訪問時間 get active time
137
138 importtime139
140 filepath = '/home/sy/下載/chls'
141
142 result =os.path.getctime(filepath)143 print(time.ctime(result))144
145 result =os.path.getmtime(filepath)146 print(time.ctime(result))147
148 result =os.path.getatime(filepath)149 print(time.ctime(result))150
151 #exists() 檢測某個路徑是否真實存在
152 filepath = '/home/sy/下載/chls'
153 result =os.path.exists(filepath)154 print(result)155
156 #isabs() 檢測一個路徑是否是絕對路徑
157 path = '/boys'
158 result =os.path.isabs(path)159 print(result)160
161 #samefile() 檢測2個路徑是否是同一個文件
162 path1 = '/home/sy/下載/001'
163 path2 = '../../../下載/001'
164 result =os.path.samefile(path1,path2)165 print(result)166
167
168 #os.environ 用于獲取和設置系統環境變量的內置值
169 #獲取系統環境變量 getenv() 效果
170 print(os.environ['PATH'])171
172 #設置系統環境變量 putenv()
173 os.environ['PATH'] += ':/home/sy/下載'
174 os.system('chls')
sys模塊 常用命令
1 importsys2
3 sys.argv: #實現從程序外部向程序傳遞參數。
4
5 sys.exit([arg]): #程序中間的退出,arg=0為正常退出。
6
7 sys.getdefaultencoding(): #獲取系統當前編碼,一般默認為ascii。
8
9 sys.setdefaultencoding(): """設置系統默認編碼,執行dir(sys)時不會看到這個方法,在解釋器中執行不通過,可以先執行reload(sys),在執行 setdefaultencoding('utf8'),此時將系統默認編碼設置為utf8。(見設置系統默認編碼 )"""
10
11 sys.getfilesystemencoding():"""獲取文件系統使用編碼方式,Windows下返回'mbcs',mac下返回'utf-8'."""
12
13 sys.path: """獲取指定模塊搜索路徑的字符串集合,可以將寫好的模塊放在得到的某個路徑下,就可以在程序中import時正確找到。"""
14
15 sys.platform: #獲取當前系統平臺。
16
17 sys.stdin,sys.stdout,sys.stderr: stdin , stdout , 以及stderr 變量包含與標準I/O 流對應的流對象. 如果需要更好地控制輸出,而print 不能滿足你的要求, 它們就是你所需要的. 你也可以替換它們, 這時候你就可以重定向輸出和輸入到其它設備( device ), 或者以非標準的方式處理它們
json模塊,pickle模塊,shelve模塊 常用命令
基本的數據序列化
1 json字符串轉為字典2 json.load /json.loads3 """兩個方法功能類似,可選參數也相同,最大的區別在于,json.load方法接受的輸入,即第一個參數,是包含json數據的文件對象,如open方法的返回對象,"""
4
5 json.loads"""接受的輸入是json字符串,而非文件對象。從輸入類型的區別也可以看出兩者的使用場合。6 可選參數包括是否需要轉換整型、浮點型等數值的參數,還有一些復雜的功能,暫時沒有用到,以后有機會再了解。"""
7
8 字典轉換為json9 json.dump /json.dumps10 """對應于load和loads,dump的第一個參數是對象字典,第二個參數是文件對象,可以直接將轉換后的json數據寫入文件,dumps的第一個參數是對象字典,其余都是可選參數。dump和dumps的可選參數相同,這些參數都相當實用,"""
11
12 pickle模塊13 (需要使用"wb"的方法寫入文件,寫的是字節)14 pickle提供了一個簡單的持久化功能。可以將對象以文件的形式存放在磁盤上。15 pickle模塊只能在python中使用,python中幾乎所有的數據類型(列表,字典,集合,類等)都可以用pickle來序列化,16 pickle序列化后的數據,可讀性差,人一般無法識別。17
18 pickle.dump(obj,file,[protocol])19 """序列化對象,并將結果數據流寫入到文件對象中。參數protocol是序列化模式,默認值為0,表示以文本的形式序列化。protocol的值還可以是1或2,表示以二進制的形式序列化。"""
20
21 pickle.load(file)22 """反序列化對象。將文件中的數據解析為一個Python對象。23 其中要注意的是,在load(file)的時候,要讓python能夠找到類的定義,否則會報錯"""
24
25 shelve模塊26 """shelve是一額簡單的數據存儲方案,他只有一個函數就是open(),這個函數接收一個參數就是文件名,并且文件名必須是.bat類型的。然后返回一個shelf對象,你可以用他來存儲東西,就可以簡單的把他當作一個字典,當你存儲完畢的時候,就調用close函數來關閉,不過在shelve模塊中,key必須為字符串,而值可以是python所支持的數據類型。"""
xml模塊 常用命令
xml是實現不同語言或程序之間進行數據交換的協議,跟json差不多,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,大家只能選擇用xml呀,至今很多傳統公司如金融行業的很多系統的接口還主要是xml。
1 #查詢:
2 #.tag 根標簽名
3 #.attrib 標簽屬性
4 #.text 標簽實際包裹的內容
5 #.iter #想取到每個屬性中的year的text值就應該用iter方法這樣取
6 #修改添加:
7 #.set 給這個標簽增加一個屬性
8 #.write直接把修改的寫入到文件中
9 #刪除:
10 #.findall 找多個標簽
11 #.find 找單個標簽
12 #.remove刪除
13
14 importxml.etree.ElementTree as ET15
16 tree = ET.parse("xmltest.xml") """parse解析,用ET模塊下的parse這個方法把xml文件解析開,解析開拿到一個tree,tree就是一個對象"""
17 root = tree.getroot()#這個對象可以調用方法,getroot就是根的意思
18 print(root.tag)19 #遍歷xml文檔,使用for循環
20 for child inroot:21 print(child.tag, child.attrib)22 for i inchild:23 print(i.tag,i.text)24
25 #只遍歷year 節點
26 for node in root.iter('year'):27 print(node.tag,node.text)28
29 #修改和刪除xml文檔內容
30 importxml.etree.ElementTree as ET31
32 tree = ET.parse("xmltest.xml")33 root =tree.getroot()34
35 #修改
36 for node in root.iter('year'):37 new_year = int(node.text) + 1
38 node.text =str(new_year)39 node.set("updated","yes")40
41 tree.write("xmltest.xml")42
43 #刪除node
44 for country in root.findall('country'):45 rank = int(country.find('rank').text)46 if rank > 50:47 root.remove(country)48
49 tree.write('output.xml')50
51 #自己創建xml文檔
52
53 importxml.etree.ElementTree as ET54
55 new_xml = ET.Element("namelist")#創建了一個根節點
56 #相當于創建了
57 name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})58 #創建一個子標簽name,然后增加一個屬性
59 age = ET.SubElement(name,"age",attrib={"checked":"no"})60 sex = ET.SubElement(name,"sex")61 sex.text = '33'
62 name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})63 age = ET.SubElement(name2,"age")64 age.text = '19'
65
66 et = ET.ElementTree(new_xml) #生成文檔對象
67 et.write("test.xml", encoding="utf-8",xml_declaration=True)68
69 ET.dump(new_xml) #打印生成的格式
re模塊 常用命令
正則表達式本身是一種小型的、高度專業化的編程語言,而在python中,通過內嵌集成re模塊,程序媛們可以直接調用來實現正則匹配。正則表達式模式被編譯成一系列的字節碼,然后由用C編寫的匹配引擎執行。
1 .#通配符
2 """需要字符串里完全符合,匹配規則,就匹配,(規則里的.元字符)可以是任何一個字符,匹配任意除換行符"\n"外的字符(在DOTALL模式中也能匹配換行符)"""
3 #!/usr/bin/env python
4 #-*- coding:utf-8 -*-
5 import re #第一步,要引入re模塊
6 ret=re.findall("匹..則", "匹配規則這個字符串是否匹配") """需要字符串里完全符合,匹配規則,就匹配,(規則里的.元字符)可以是任何一個字符"""
7 print(ret)8 #打印出['匹配規則']
9
10 ^ #元字符
11 """字符串開始位置與匹配規則符合就匹配,否則不匹配,匹配字符串開頭。在多行模式中匹配每一行的開頭,^元字符如果寫到[]字符集里就是反取"""
12 #!/usr/bin/env python
13 #-*- coding:utf-8 -*-
14 import re #第一步,要引入re模塊
15 a = re.findall("^匹配規則", "匹配規則這個字符串是否匹配") """字符串開始位置與匹配規則符合就匹配,否則不匹配"""
16 print(a) #以列表形式返回匹配到的字符串
17 #打印出 ['匹配規則']
18
19 $ #元字符
20 """字符串結束位置與匹配規則符合就匹配,否則不匹配,匹配字符串末尾,在多行模式中匹配每一行的末尾"""
21 #!/usr/bin/env python
22 #-*- coding:utf-8 -*-
23 import re #第一步,要引入re模塊
24 a = re.findall("匹配規則$", "這個字符串是否匹配規則") """字符串結束位置與匹配規則符合就匹配,否則不匹配"""
25 print(a) #以列表形式返回匹配到的字符串
26 #打印出 ['匹配規則']
27
28 * #元字符
29 """需要字符串里完全符合,匹配規則,就匹配,(規則里的*元字符)前面的一個字符可以是0個或多個原本字符,匹配前一個字符0或多次,貪婪匹配前導字符有多少個就匹配多少個很貪婪,如果規則里只有一個分組,盡量避免用*否則會有可能匹配出空字符串"""
30 #!/usr/bin/env python
31 #-*- coding:utf-8 -*-
32 import re #第一步,要引入re模塊
33 a = re.findall("匹配規則*", "這個字符串是否匹配規則則則則則") """需要字符串里完全符合,匹配規則,就匹配,(規則里的*元字符)前面的一個字符可以是0或多個原本字符"""
34 print(a) #以列表形式返回匹配到的字符串
35 #打印出 ['匹配規則則則則則']
36
37 + #元字符
38 """需要字符串里完全符合,匹配規則,就匹配,(規則里的+元字符)前面的一個字符可以是1個或多個原本字符,匹配前一個字符1次或無限次,貪婪匹配前導字符有多少個就匹配多少個很貪婪"""
39 #!/usr/bin/env python
40 #-*- coding:gbk -*-
41 import re #第一步,要引入re模塊
42 a = re.findall("匹配+", "匹配配配配配規則這個字符串是否匹配規則則則則則") """需要字符串里完全符合,匹配規則,就匹配,(規則里的+元字符)前面的一個字符可以是1個或多個原本字符"""
43 print(a) #以列表形式返回匹配到的字符串
44 #打印出 ['匹配配配配配', '匹配']
45
46 ? #元字符,和防止貪婪匹配
47 """需要字符串里完全符合,匹配規則,就匹配,(規則里的?元字符)前面的一個字符可以是0個或1個原本字符,匹配一個字符0次或1次,還有一個功能是可以防止貪婪匹配,詳情見防貪婪匹配"""
48 #!/usr/bin/env python
49 #-*- coding:utf-8 -*-
50 import re #第一步,要引入re模塊
51 a = re.findall("匹配規則?", "匹配規這個字符串是否匹配規則則則則則") """需要字符串里完全符合,匹配規則,就匹配,(規則里的?元字符)前面的一個字符可以是0個或1個原本字符"""
52 print(a) #以列表形式返回匹配到的字符串
53 #打印出 ['匹配規', '匹配規則']
54
55 {} #元字符,范圍
56 """需要字符串里完全符合,匹配規則,就匹配,(規則里的 {} 元字符)前面的一個字符,是自定義字符數,位數的原本字符57 {m}匹配前一個字符m次,{m,n}匹配前一個字符m至n次,若省略n,則匹配m至無限次58 {0,}匹配前一個字符0或多次,等同于*元字符59 {+,}匹配前一個字符1次或無限次,等同于+元字符60 {0,1}匹配前一個字符0次或1次,等同于?元字符"""
61 #!/usr/bin/env python
62 #-*- coding:utf-8 -*-
63 import re #第一步,要引入re模塊
64 a = re.findall("匹配規則{3}", "匹配規這個字符串是否匹配規則則則則則") """{m}匹配前一個字符m次,{m,n}匹配前一個字符m至n次,若省略n,則匹配m至無限次"""
65 print(a) #以列表形式返回匹配到的字符串
66 #打印出 ['匹配規則則則']
67
68 [] #元字符,字符集
69 """. % * + ? () {} 出現在中括號中僅表示字符本身。^字符在中括號中表示取反。70 需要字符串里完全符合,匹配規則,就匹配,(規則里的 [] 元字符)對應位置是[]里的任意一個字符就匹配71 字符集。對應的位置可以是字符集中任意字符。字符集中的字符可以逐個列出,也可以給出范圍,如[abc]或[a-c]。[^abc]表示取反,即非abc。72 所有特殊字符在字符集中都失去其原有的特殊含義。用\反斜杠轉義恢復特殊字符的特殊含義。"""
73 #!/usr/bin/env python
74 #-*- coding:utf-8 -*-
75 import re #第一步,要引入re模塊
76 a = re.findall("匹配[a,b,c]規則", "匹配a規則這個字符串是否匹配b規則則則則則") """需要字符串里完全符合,匹配規則,就匹配,(規則里的 [] 元字符)對應位置是[]里的任意一個字符就匹配"""
77 print(a) #以列表形式返回匹配到的字符串
78
79 [^] #非,反取,匹配出除[^]里面的字符,^元字符如果寫到字符集里就是反取
80 #!/usr/bin/env python
81 #-*- coding:utf-8 -*-
82 import re #第一步,要引入re模塊
83 a = re.findall("[^a-z]", "匹配s規則這s個字符串是否s匹配f規則則re則則則") #反取,匹配出除字母外的字符
84 print(a) #以列表形式返回匹配到的字符串
85 #打印出 ['匹', '配', '規', '則', '這', '個', '字', '符', '串', '是', '否', '匹', '配', '規', '則', '則', '則', '則', '則']
86
87 () #元字符,分組
88 """也就是分組匹配,()里面的為一個組也可以理解成一個整體89 如果()后面跟的是特殊元字符如 (adc)* 那么*控制的前導字符就是()里的整體內容,不再是前導一個字符"""
90 #列1
91 #!/usr/bin/env python
92 #-*- coding:utf8 -*-
93 import re #第一步,要引入re模塊
94 #也就是分組匹配,()里面的為一個組也可以理解成一個整體
95 a = re.search("(a4)+", "a4a4a4a4a4dg4g654gb") #匹配一個或多個a4
96 b =a.group()97 print(b)98 #打印出 a4a4a4a4a4
99 #列2
100 #!/usr/bin/env python
101 #-*- coding:utf8 -*-
102 import re #第一步,要引入re模塊
103 #也就是分組匹配,()里面的為一個組也可以理解成一個整體
104 a = re.search("a(\d+)", "a466666664a4a4a4dg4g654gb") #匹配 (a) (\d0-9的數字) (+可以是1個到多個0-9的數字)
105 b =a.group()106 print(b)107 #打印出 a466666664
108
109 | #元字符,或
110 #或就是前后其中一個符合就匹配
111 #!/usr/bin/env python
112 #-*- coding:utf8 -*-
113 import re #第一步,要引入re模塊
114 a = re.findall(r"你|好", "a4a4a你4aabc4a4dgg好dg4g654g") #|或,或就是前后其中一個符合就匹配
115 print(a)116 #打印出 ['你', '好']
117
118 r #原生字符
119 """將在python里有特殊意義的字符如\b,轉換成原生字符(就是去除它在python的特殊意義),不然會給正則表達式有沖突,為了避免這種沖突可以在規則前加原始字符r"""
120
121 """貪婪和非貪婪122 正則表達式通常用于在文本中查找匹配的字符串。Python里數量詞默認是貪婪的(在少數語言里也可能是默認非貪婪),總是嘗試匹配盡可能多的字符;非貪婪則相反,總是嘗試匹配盡可能少的字符。在"*","?","+","{m,n}"后面加上?,使貪婪變成非貪婪。123 貪婪模式下字符串查找會直接走到字符串結尾去匹配,如果不相等就向前尋找,這一過程稱為回溯。"""
124 importre125 str1='
貪婪'126 str2=re.findall(r'<.*>',str1)127 print(str2)128 >>>['
']129130 #非貪婪模式下會自左向右查找,一個一個匹配不會出現回溯的情況。
131 importre132 str1='
貪婪'133 str2=re.findall(r'<.*?>',str1)134 print(str2)135 >>>['
']136137 \ #正則轉義符
138 #在使用時需在字符串外加上 r 來取消轉義
139
140 \d #數字
141 importre142 str1='iii amiiii 123er45vg44'
143 str2=re.findall(r'\d',str1)144 print(str2)145 >>>['1', '2', '3', '4', '5', '4', '4']146
147 \D #匹配數字以外的字符
148 importre149 str1='i love python12456'
150 str2=re.findall(r'\D',str1)151 print(str2)152 >>>['i', ' ', 'l', 'o', 'v', 'e', ' ', 'p', 'y', 't', 'h', 'o', 'n']153
154 \w #字母、數字、漢字和下劃線
155 importre156 str1='iii am_你好iiii 123er45vg44'
157 str2=re.findall(r'\w',str1)158 print(str2)159 >>>['i', 'i', 'i', 'a', 'm', '_', '你', '好', 'i', 'i', 'i', 'i', '1', '2', '3', 'e', 'r', '4', '5', 'v', 'g', '4', '4']160
161 \W #非\w匹配的字符
162 importre163 str1='i love ¥%*python12456\n\t'
164 str2=re.findall(r'\W',str1)165 print(str2)166 >>>[' ', ' ', '¥', '%', '*', '\n', '\t']167
168 \s #匹配空白符號(\n,\t和空格)
169 importre170 str1='iii am_你好iiii 123\ner\t45vg44'
171 str2=re.findall(r'\s',str1)172 print(str2)173 >>>[' ', ' ', '\n', '\t', ' ']174
175 \S #匹配除了空白字符之外的
176 importre177 str1='i love python12456\n\t'
178 str2=re.findall(r'\S',str1)179 print(str2)180 >>>['i', 'l', 'o', 'v', 'e', 'p', 'y', 't', 'h', 'o', 'n', '1', '2', '4', '5', '6']181
182 \b #單詞邊界
183 """字符的位置是非常重要的。如果它位于要匹配的字符串的開始,它在單詞的開始處查找匹配項。如果它位于字符串的結尾,它在單詞的結尾處查找匹配項。"""
184 importre185 str1='i love python'
186 str2=re.findall(r'\bon',str1)187 str3=re.findall(r'on\b',str1)188 print(str2)189 print(str3)190 >>>[]191 ['on']192
193 \B #匹配非單詞邊界
194 """對于 \B 非字邊界運算符,位置并不重要,因為匹配不關心究竟是單詞的開頭還是結尾。"""
195 importre196 str1='i love python12456'
197 str2=re.findall(r'ov\B',str1)198 print(str2)199 >>>['ov']200
201 #re模塊下的常用方法
202 findall()203 #re.findall 遍歷匹配,可以獲取字符串中所有匹配的字符串,返回一個列表。
204 #格式:
205 re.findall(pattern, string, flags=0)206 p = re.compile(r'\d+')207 print(p.findall('o1n2m3k4'))208 執行結果如下:209 ['1', '2', '3', '4']210
211 importre212 tt = "Tina is a good girl, she is cool, clever, and so on..."
213 rr = re.compile(r'\w*oo\w*')214 print(rr.findall(tt))215 print(re.findall(r'(\w)*oo(\w)',tt))#()表示子表達式
216 執行結果如下:217 ['good', 'cool']218 [('g', 'd'), ('c', 'l')]219
220 search()221 #格式:
222 re.search(pattern, string, flags=0)223 #re.search函數會在字符串內查找模式匹配,只要找到第一個匹配然后返回,如果字符串沒有匹配,則返回None。
224
225 print(re.search('\dcom','www.4comrunoob.5com').group())226 #執行結果如下:
227 4com228 """注:match和search一旦匹配成功,就是一個match object對象,而match object對象有以下方法:229 group() 返回被 RE 匹配的字符串230 start() 返回匹配開始的位置231 end() 返回匹配結束的位置232 span() 返回一個元組包含匹配 (開始,結束) 的位置233 group() 返回re整體匹配的字符串,可以一次輸入多個組號,對應組號匹配的字符串234 group()返回re整體匹配的字符串,235 group (n,m) 返回組號為n,m所匹配的字符串,如果組號不存在,則返回indexError異常236 groups()groups() 方法返回一個包含正則表達式中所有小組字符串的元組,從 1 到所含的小組號,通常groups()不需要參數,返回一個元組,元組中的元就是正則表達式中定義的組。"""
237
238 importre239 a = "123abc456"
240 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) #123abc456,返回整體
241 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) #123
242 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) #abc
243 print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) #456
244 """group(1) 列出第一個括號匹配部分,group(2) 列出第二個括號匹配部分,group(3) 列出第三個括號匹配部分。"""
245
246 match()247 """決定RE是否在字符串剛開始的位置匹配。//注:這個方法并不是完全匹配。當pattern結束時若string還有剩余字符,仍然視為成功。想要完全匹配,可以在表達式末尾加上邊界匹配符'$'"""
248 #格式:
249 re.match(pattern, string, flags=0)250
251 print(re.match('com','comwww.runcomoob').group())252 print(re.match('com','Comwww.runcomoob',re.I).group())253 #執行結果如下:
254 com255 com256
257 split()258 """按照能夠匹配的子串將string分割后返回列表。259 可以使用re.split來分割字符串,如:re.split(r'\s+', text);將字符串按空格分割成一個單詞列表。"""
260 #格式:
261 re.split(pattern, string[, maxsplit])262 #maxsplit用于指定最大分割次數,不指定將全部分割。
263
264 print(re.split('\d+','one1two2three3four4five5'))265 #執行結果如下:
266 ['one', 'two', 'three', 'four', 'five', '']267
268 sub()269 #使用re替換string中每一個匹配的子串后返回替換后的字符串。
270 #格式:
271 re.sub(pattern, repl, string, count)272
273 importre274 text = "JGood is a handsome boy, he is cool, clever, and so on..."
275 print(re.sub(r'\s+', '-', text))276 #執行結果如下:
277 JGood-is-a-handsome-boy,-he-is-cool,-clever,-and-so-on...278 """其中第二個函數是替換后的字符串;本例中為'-'第四個參數指替換個數。默認為0,表示每個匹配項都替換。"""
279 #re.sub還允許使用函數對匹配項的替換進行復雜的處理。
280 """如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);將字符串中的空格' '替換為'[ ]'。"""
281 importre282 text = "JGood is a handsome boy, he is cool, clever, and so on..."
283 print(re.sub(r'\s+', lambda m:'['+m.group(0)+']', text,0))284 #執行結果如下:
285 JGood[ ]is[ ]a[ ]handsome[ ]boy,[ ]he[ ]is[ ]cool,[ ]clever,[ ]and[ ]so[ ]on...286
287 subn()288 #返回替換次數
289 #格式:
290 subn(pattern, repl, string, count=0, flags=0)291
292 print(re.subn('[1-2]','A','123456abcdef'))293 print(re.sub("g.t","have",'I get A, I got B ,I gut C'))294 print(re.subn("g.t","have",'I get A, I got B ,I gut C'))295 #執行結果如下:
296 ('AA3456abcdef', 2)297 I have A, I have B ,I have C298 ('I have A, I have B ,I have C', 3)299
300 compile()301 """編譯正則表達式模式,返回一個對象的模式。(可以把那些常用的正則表達式編譯成正則表達式對象,這樣可以提高一點效率。)"""
302 #格式:
303 re.compile(pattern,flags=0)304 #pattern: 編譯時用的表達式字符串。
305 """flags 編譯標志位,用于修改正則表達式的匹配方式,如:是否區分大小寫,多行匹配等。常用的flags有:"""
306 re.S(DOTALL)307 #使.匹配包括換行在內的所有字符
308 re.I(IGNORECASE)309 #使匹配對大小寫不敏感
310 re.L(LOCALE)311 #做本地化識別(locale-aware)匹配,法語等
312 re.M(MULTILINE)313 #多行匹配,影響^和$
314 re.X(VERBOSE)315 #該標志通過給予更靈活的格式以便將正則表達式寫得更易于理解
316 re.U317 #根據Unicode字符集解析字符,這個標志影響\w,\W,\b,\B
318 importre319 tt = "Tina is a good girl, she is cool, clever, and so on..."
320 rr = re.compile(r'\w*oo\w*')321 print(rr.findall(tt)) #查找所有包含'oo'的單詞
322 #執行結果如下:
323 ['good', 'cool']324
325 finditer()326 """搜索string,返回一個順序訪問每一個匹配結果(Match對象)的迭代器。找到 RE 匹配的所有子串,并把它們作為一個迭代器返回。"""
327 #格式:
328 re.finditer(pattern, string, flags=0)329
330 iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...')331 for i initer:332 print(i)333 print(i.group())334 print(i.span())335 #執行結果如下:
336 <_sre.SRE_Match object; span=(0, 2), match='12'>
337 12
338 (0, 2)339 <_sre.SRE_Match object; span=(8, 10), match='44'>
340 44
341 (8, 10)342 <_sre.SRE_Match object; span=(24, 26), match='11'>
343 11
344 (24, 26)345 <_sre.SRE_Match object; span=(31, 33), match='10'>
346 10
347 (31, 33)348
349 """瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中,未匹配成功返回空列表350 注意:一旦匹配成,再次匹配,是從前一次匹配成功的,后面一位開始的,也可以理解為匹配成功的字符串,不在參與下次匹配"""
351 #!/usr/bin/env python
352 #-*- coding:utf8 -*-
353 importre354 #無分組
355 r = re.findall("\d+\w\d+", "a2b3c4d5") """瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中"""
356 print(r)357 #輸出結果
358 #['2b3', '4d5']
359 """注意:匹配成功的字符串,不在參與下次匹配,所以3c4也符合規則但是沒匹配到,注意:如果沒寫匹配規則,也就是空規則,返回的是一個比原始字符串多一位的,空字符串列表"""
360 #!/usr/bin/env python
361 #-*- coding:utf8 -*-
362 importre363 #無分組
364 r = re.findall("", "a2b3c4d5") """瀏覽全部字符串,匹配所有合規則的字符串,匹配到的字符串放到一個列表中"""
365 print(r)366 #輸出結果
367 #['', '', '', '', '', '', '', '', '']
368 """注意:如果沒寫匹配規則,也就是空規則,返回的是一個比原始字符串多一位的,空字符串列表"""
369
370 """注意:正則匹配到空字符的情況,如果規則里只有一個組,而組后面是*就表示組里的內容可以是0個或者多過,這樣組里就有了兩個意思,一個意思是匹配組里的內容,二個意思是匹配組里0內容(即是空白)所以盡量避免用*否則會有可能匹配出空字符串371 注意:正則只拿組里最后一位,如果規則里只有一個組,匹配到的字符串里在拿組內容是,拿的是匹配到的內容最后一位"""
372 #!/usr/bin/env python
373 #-*- coding:utf8 -*-
374 importre375 origin = "hello alex bcd alex lge alex acd 19"
376 r = re.findall("(a)*", origin)377 print(r)378 #輸出結果
379 ['', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', '', '', '', '', 'a', '', '', '', '', 'a', '', '', '', '', '', '']380
381 #有分組:只將匹配到的字符串里,組的部分放到列表里返回,相當于groups()方法
382 #!/usr/bin/env python
383 #-*- coding:utf8 -*-
384 importre385 origin = "hello alex bcd alex lge alex acd 19"
386 r = re.findall("a(\w+)", origin) #有分組:只將匹配到的字符串里,組的部分放到列表里返回
387 print(r)388 #輸出結果
389 #['lex', 'lex', 'lex', 'cd']
390
391 """多個分組:只將匹配到的字符串里,組的部分放到一個元組中,最后將所有元組放到一個列表里返392 相當于在group()結果里再將組的部分,分別,拿出來放入一個元組,最后將所有元組放入一個列表返回"""
393
394 #!/usr/bin/env python
395 #-*- coding:utf8 -*-
396 importre397 origin = "hello alex bcd alex lge alex acd 19"
398 r = re.findall("(a)(\w+)", origin) """多個分組:只將匹配到的字符串里,組的部分放到一個元組中,最后將所有元組放到一個列表里返回"""
399 print(r)400 #輸出結果
401 #[('a', 'lex'), ('a', 'lex'), ('a', 'lex'), ('a', 'cd')]
402
403 """分組中有分組:只將匹配到的字符串里,組的部分放到一個元組中,先將包含有組的組,看作一個整體也就是一個組,把這個整體組放入一個元組里,然后在把組里的組放入一個元組,最后將所有組放入一個列表返回"""
404
405 #!/usr/bin/env python
406 #-*- coding:utf8 -*-
407 importre408 origin = "hello alex bcd alex lge alex acd 19"
409 r = re.findall("(a)(\w+(e))", origin) """分組中有分組:只將匹配到的字符串里,組的部分放到一個元組中,先將包含有組的組,看作一個整體也就是一個組,把這個整體組放入一個元組里,然后在把組里的組放入一個元組,最后將所有組放入一個列表返回"""
410 print(r)411 #輸出結果
412 [('a', 'le', 'e'), ('a', 'le', 'e'), ('a', 'le', 'e')]413
414 ?: """在有分組的情況下findall()函數,不只拿分組里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正則對象的函數如findall()"""
415
416 #!/usr/bin/env python
417 #-*- coding:utf8 -*-
418 importre419 origin = "hello alex bcd alex lge alex acd 19"
420 b = re.findall("a(?:\w+)",origin) """?:在有分組的情況下,不只拿分組里的字符串,拿所有匹配到的字符串,注意?:只用于不是返回正則對象的函數如findall()"""
421 print(b)422 #輸出
423 ['alex', 'alex', 'alex', 'acd']424
425 #特殊分組用法表:只對正則函數返回對象的有用
426 (?P)427 """?P<>定義組里匹配內容的key(鍵),<>里面寫key名稱,值就是匹配到的內容,在用groupdict()方法打印字符串"""
428 (?Pabc){2}429
430 (?P=name)431 #引用別名為的分組匹配到字符串
432 (?P\d)abc(?P=id)433
434 \
435 #引用編號為的分組匹配到字符串
436 (\d)abc\1
configparser模塊 常用命令
來看一個好多軟件的常見文檔格式如下:
1 [DEFAULT]2 ServerAliveInterval = 45
3 Compression =yes4 CompressionLevel = 9
5 ForwardX11 =yes6
7 [bitbucket.org]8 User =hg9
10 [topsecret.server.com]11 Port = 50022
12 ForwardX11 = no
如果想用python生成一個這樣的文檔怎么做呢?
1 importconfigparser2
3 config =configparser.ConfigParser()4 config["DEFAULT"] = {'ServerAliveInterval': '45',5 'Compression': 'yes',6 'CompressionLevel': '9'}7
8 config['bitbucket.org'] ={}9 config['bitbucket.org']['User'] = 'hg'
10 config['topsecret.server.com'] ={}11 topsecret = config['topsecret.server.com']12 topsecret['Host Port'] = '50022' #mutates the parser
13 topsecret['ForwardX11'] = 'no' #same here
14 config['DEFAULT']['ForwardX11'] = 'yes'
15 with open('example.ini', 'w') as configfile:16 config.write(configfile)
增刪改查操作
1 importconfigparser2
3 config =configparser.ConfigParser()4
5 #---------------------------------------------查
6 print(config.sections()) #[]
7
8 config.read('example.ini')9
10 print(config.sections()) #['bitbucket.org', 'topsecret.server.com']
11
12 print('bytebong.com' in config)#False
13
14 print(config['bitbucket.org']['User']) #hg
15
16 print(config['DEFAULT']['Compression']) #yes
17
18 print(config['topsecret.server.com']['ForwardX11']) #no
19
20
21 for key in config['bitbucket.org']:22 print(key)23
24
25 #user
26 #serveraliveinterval
27 #compression
28 #compressionlevel
29 #forwardx11
30
31
32 print(config.options('bitbucket.org'))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11']
33 print(config.items('bitbucket.org')) #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')]
34
35 print(config.get('bitbucket.org','compression'))#yes
36
37
38 #---------------------------------------------刪,改,增(config.write(open('i.cfg', "w")))
39
40
41 config.add_section('yuan')42
43 config.remove_section('topsecret.server.com')44 config.remove_option('bitbucket.org','user')45
46 config.set('bitbucket.org','k1','11111')47
48 config.write(open('i.cfg', "w"))
hashlib模塊 常用命令
用于加密相關的操作,3.x里代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
1 importhashlib2
3 m=hashlib.md5()#m=hashlib.sha256()
4
5 m.update('hello'.encode('utf8'))6 print(m.hexdigest()) #5d41402abc4b2a76b9719d911017c592
7
8 m.update('alvin'.encode('utf8'))9
10 print(m.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
11
12 m2=hashlib.md5()13 m2.update('helloalvin'.encode('utf8'))14 print(m2.hexdigest()) #92a7e713c30abbb0319fa07da2a5c4af
以上加密算法雖然依然非常厲害,但時候存在缺陷,即:通過撞庫可以反解。所以,有必要對加密算法中添加自定義key再來做加密。
1 importhashlib2
3 ######### 256 ########
4
5 hash = hashlib.sha256('898oaFs09f'.encode('utf8'))6 hash.update('alvin'.encode('utf8'))7 print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7
python 還有一個 hmac 模塊,它內部對我們創建 key 和 內容 再進行處理然后再加密:
1 importhmac2 h = hmac.new('alvin'.encode('utf8'))3 h.update('hello'.encode('utf8'))4 print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940
subprocess模塊 常用命令
當我們需要調用系統的命令的時候,最先考慮的os模塊。用os.system()和os.popen()來進行操作。但是這兩個命令過于簡單,不能完成一些復雜的操作,如給運行的命令提供輸入或者讀取命令的輸出,判斷該命令的運行狀態,管理多個命令的并行等等。這時subprocess中的Popen命令就能有效的完成我們需要的操作。
subprocess模塊允許一個進程創建一個新的子進程,通過管道連接到子進程的stdin/stdout/stderr,獲取子進程的返回值等操作。
1 #Popen它的構造函數如下:
2
3 subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None,stderr=None, preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)4
5 #參數args可以是字符串或者序列類型(如:list,元組),用于指定進程的可執行文件及其參數。
6 #如果是序列類型,第一個元素通常是可執行文件的路徑。我們也可以顯式的使用executeable參
7 #數來指定可執行文件的路徑。在windows操作系統上,Popen通過調用CreateProcess()來創
8 #建子進程,CreateProcess接收一個字符串參數,如果args是序列類型,系統將會通過
9 #list2cmdline()函數將序列類型轉換為字符串。
10 #
11 #
12 #參數bufsize:指定緩沖。我到現在還不清楚這個參數的具體含義,望各個大牛指點。
13 #
14 #參數executable用于指定可執行程序。一般情況下我們通過args參數來設置所要運行的程序。如
15 #果將參數shell設為True,executable將指定程序使用的shell。在windows平臺下,默認的
16 #shell由COMSPEC環境變量來指定。
17 #
18 #參數stdin, stdout, stderr分別表示程序的標準輸入、輸出、錯誤句柄。他們可以是PIPE,
19 #文件描述符或文件對象,也可以設置為None,表示從父進程繼承。
20 #
21 #參數preexec_fn只在Unix平臺下有效,用于指定一個可執行對象(callable object),它將
22 #在子進程運行之前被調用。
23 #
24 #參數Close_sfs:在windows平臺下,如果close_fds被設置為True,則新創建的子進程將不會
25 #繼承父進程的輸入、輸出、錯誤管道。我們不能將close_fds設置為True同時重定向子進程的標準
26 #輸入、輸出與錯誤(stdin, stdout, stderr)。
27 #
28 #如果參數shell設為true,程序將通過shell來執行。
29 #
30 #參數cwd用于設置子進程的當前目錄。
31 #
32 #參數env是字典類型,用于指定子進程的環境變量。如果env = None,子進程的環境變量將從父
33 #進程中繼承。
34 #
35 #參數Universal_newlines:不同操作系統下,文本的換行符是不一樣的。如:windows下
36 #用’/r/n’表示換,而Linux下用’/n’。如果將此參數設置為True,Python統一把這些換行符當
37 #作’/n’來處理。
38 #
39 #參數startupinfo與createionflags只在windows下用效,它們將被傳遞給底層的
40 #CreateProcess()函數,用于設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。
簡單命令:
1 importsubprocess2
3 a=subprocess.Popen('ls')#創建一個新的進程,與主進程不同步
4
5 print('>>>>>>>',a)#a是Popen的一個實例對象
6
7 '''
8 >>>>>>> 9 __init__.py10 __pycache__11 log.py12 main.py13
14 '''
15
16 #subprocess.Popen('ls -l',shell=True)
17
18 #subprocess.Popen(['ls','-l'])
subprocess.PIPE
在創建Popen對象時,subprocess.PIPE可以初始化stdin, stdout或stderr參數。表示與子進程通信的標準流
1 importsubprocess2
3 #subprocess.Popen('ls')
4 p=subprocess.Popen('ls',stdout=subprocess.PIPE)#結果跑哪去啦?
5
6 print(p.stdout.read())#這這呢:b'__pycache__\nhello.py\nok.py\nweb\n'
這是因為subprocess創建了子進程,結果本在子進程中,if 想要執行結果轉到主進程中,就得需要一個管道,即 : stdout=subprocess.PIPE
subprocess.STDOUT
創建Popen對象時,用于初始化stderr參數,表示將錯誤通過標準輸出流輸出。
Popen的方法
1 Popen.poll()2 用于檢查子進程是否已經結束。設置并返回returncode屬性。3
4 Popen.wait()5 等待子進程結束。設置并返回returncode屬性。6
7 Popen.communicate(input=None)8 與子進程進行交互。向stdin發送數據,或從stdout和stderr中讀取數據。可選參數input指定發送到子進程的參數。 Communicate()返回一個元組:(stdoutdata, stderrdata)。注意:如果希望通過進程的stdin向其發送數據,在創建Popen對象的時候,參數stdin必須被設置為PIPE。同樣,如 果希望從stdout和stderr獲取數據,必須將stdout和stderr設置為PIPE。9
10 Popen.send_signal(signal)11 向子進程發送信號。12
13 Popen.terminate()14 停止(stop)子進程。在windows平臺下,該方法將調用Windows API TerminateProcess()來結束子進程。15
16 Popen.kill()17 殺死子進程。18
19 Popen.stdin20 如果在創建Popen對象是,參數stdin被設置為PIPE,Popen.stdin將返回一個文件對象用于策子進程發送指令。否則返回None。21
22 Popen.stdout23 如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用于策子進程發送指令。否則返回 None。24
25 Popen.stderr26 如果在創建Popen對象是,參數stdout被設置為PIPE,Popen.stdout將返回一個文件對象用于策子進程發送指令。否則返回 None。27
28 Popen.pid29 獲取子進程的進程ID。30
31 Popen.returncode32 獲取進程的返回值。如果進程還沒有結束,返回None。
supprocess模塊的工具函數
1 supprocess模塊提供了一些函數,方便我們用于創建進程來實現一些簡單的功能。2
3 subprocess.call(*popenargs, **kwargs)4 運行命令。該函數將一直等待到子進程運行結束,并返回進程的returncode。如果子進程不需要進行交 互,就可以使用該函數來創建。5
6 subprocess.check_call(*popenargs, **kwargs)7 與subprocess.call(*popenargs, **kwargs)功能一樣,只是如果子進程返回的returncode不為0的話,將觸發CalledProcessError異常。在異常對象中,包 括進程的returncode信息。8
9 check_output(*popenargs, **kwargs)10 與call()方法類似,以byte string的方式返回子進程的輸出,如果子進程的返回值不是0,它拋出CalledProcessError異常,這個異常中的returncode包含返回碼,output屬性包含已有的輸出。11
12 getstatusoutput(cmd)/getoutput(cmd)13 這兩個函數僅僅在Unix下可用,它們在shell中執行指定的命令cmd,前者返回(status, output),后者返回output。其中,這里的output包括子進程的stdout和stderr。
1 importsubprocess2
3 #1
4 #subprocess.call('ls',shell=True)
5 '''
6 hello.py7 ok.py8 web9 '''
10 #data=subprocess.call('ls',shell=True)
11 #print(data)
12 '''
13 hello.py14 ok.py15 web16 '''
17
18 #2
19 #subprocess.check_call('ls',shell=True)
20
21 '''
22 hello.py23 ok.py24 web25 '''
26 #data=subprocess.check_call('ls',shell=True)
27 #print(data)
28 '''
29 hello.py30 ok.py31 web32 '''
33 #兩個函數區別:只是如果子進程返回的returncode不為0的話,將觸發CalledProcessError異常
34
35
36
37 #3
38 #subprocess.check_output('ls')#無結果
39
40 #data=subprocess.check_output('ls')
41 #print(data) #b'hello.py\nok.py\nweb\n'
logging模塊 常用命令
一 (簡單應用)
1 importlogging2 logging.debug('debug message')3 logging.info('info message')4 logging.warning('warning message')5 logging.error('error message')6 logging.critical('critical message')
輸出:
WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message
可見,默認情況下Python的logging模塊將日志打印到了標準輸出中,且只顯示了大于等于WARNING級別的日志,這說明默認的日志級別設置為WARNING(日志級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG > NOTSET),默認的日志格式為日志級別:Logger名稱:用戶輸出消息。
二 靈活配置日志級別,日志格式,輸出位置
1 importlogging2 logging.basicConfig(level=logging.DEBUG,3 format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',4 datefmt='%a, %d %b %Y %H:%M:%S',5 filename='/tmp/test.log',6 filemode='w')7
8 logging.debug('debug message')9 logging.info('info message')10 logging.warning('warning message')11 logging.error('error message')12 logging.critical('critical message')
查看輸出:
cat /tmp/test.log
Mon, 05 May 2014 16:29:53 test_logging.py[line:9] DEBUG debug message
Mon, 05 May 2014 16:29:53 test_logging.py[line:10] INFO info message
Mon, 05 May 2014 16:29:53 test_logging.py[line:11] WARNING warning message
Mon, 05 May 2014 16:29:53 test_logging.py[line:12] ERROR error message
Mon, 05 May 2014 16:29:53 test_logging.py[line:13] CRITICAL critical message
可見在logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為,可用參數有
filename:用指定的文件名創建FiledHandler(后邊會具體講解handler的概念),這樣日志會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。
format:指定handler使用的日志顯示格式。
datefmt:指定日期時間格式。
level:設置rootlogger(后邊會講解具體概念)的日志級別
stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件(f=open('test.log','w')),默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。
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用戶輸出的消息
三 logger對象
上述幾個例子中我們了解到了logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical()(分別用以記錄不同級別的日志信息),logging.basicConfig()(用默認日志格式(Formatter)為日志系統建立一個默認的流處理器(StreamHandler),設置基礎配置(如日志級別等)并加到root logger(根Logger)中)這幾個logging模塊級別的函數,另外還有一個模塊級別的函數是logging.getLogger([name])(返回一個logger對象,如果沒有指定名字將返回root logger)
先看一個最簡單的過程:
1 importlogging2
3 logger =logging.getLogger()4 #創建一個handler,用于寫入日志文件
5 fh = logging.FileHandler('test.log')6
7 #再創建一個handler,用于輸出到控制臺
8 ch =logging.StreamHandler()9
10 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')11
12 fh.setFormatter(formatter)13 ch.setFormatter(formatter)14
15 logger.addHandler(fh) #logger對象可以添加多個fh和ch對象
16 logger.addHandler(ch)17
18 logger.debug('logger debug message')19 logger.info('logger info message')20 logger.warning('logger warning message')21 logger.error('logger error message')22 logger.critical('logger critical message')
先簡單介紹一下,logging庫提供了多個組件:Logger、Handler、Filter、Formatter。Logger對象提供應用程序可直接使用的接口,Handler發送日志到適當的目的地,Filter提供了過濾日志信息的方法,Formatter指定日志顯示格式。
(1) Logger是一個樹形層級結構,輸出信息之前都要獲得一個Logger(如果沒有顯示的獲取則自動創建并使用root Logger,如第一個例子所示)。logger = logging.getLogger()返回一個默認的Logger也即root Logger,并應用默認的日志級別、Handler和Formatter設置。當然也可以通過Logger.setLevel(lel)指定最低的日志級別,可用的日志級別有logging.DEBUG、logging.INFO、logging.WARNING、logging.ERROR、logging.CRITICAL。Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical()輸出不同級別的日志,只有日志等級大于或等于設置的日志級別的日志才會被輸出。
1 logger.debug('logger debug message')2 logger.info('logger info message')3 logger.warning('logger warning message')4 logger.error('logger error message')5 logger.critical('logger critical message')
只輸出了
2014-05-06 12:54:43,222 - root - WARNING - logger warning message
2014-05-06 12:54:43,223 - root - ERROR - logger error message
2014-05-06 12:54:43,224 - root - CRITICAL - logger critical message
從這個輸出可以看出logger = logging.getLogger()返回的Logger名為root。這里沒有用logger.setLevel(logging.Debug)顯示的為logger設置日志級別,所以使用默認的日志級別WARNIING,故結果只輸出了大于等于WARNIING級別的信息。
(2) 如果我們再創建兩個logger對象:
1 ##################################################
2 logger1 = logging.getLogger('mylogger')3 logger1.setLevel(logging.DEBUG)4
5 logger2 = logging.getLogger('mylogger')6 logger2.setLevel(logging.INFO)7
8 logger1.addHandler(fh)9 logger1.addHandler(ch)10
11 logger2.addHandler(fh)12 logger2.addHandler(ch)13
14 logger1.debug('logger1 debug message')15 logger1.info('logger1 info message')16 logger1.warning('logger1 warning message')17 logger1.error('logger1 error message')18 logger1.critical('logger1 critical message')19
20 logger2.debug('logger2 debug message')21 logger2.info('logger2 info message')22 logger2.warning('logger2 warning message')23 logger2.error('logger2 error message')24 logger2.critical('logger2 critical message')
這里有兩個個問題:
<1>我們明明通過logger1.setLevel(logging.DEBUG)將logger1的日志級別設置為了DEBUG,為何顯示的時候沒有顯示出DEBUG級別的日志信息,而是從INFO級別的日志開始顯示呢?
原來logger1和logger2對應的是同一個Logger實例,只要logging.getLogger(name)中名稱參數name相同則返回的Logger實例就是同一個,且僅有一個,也即name與Logger實例一一對應。在logger2實例中通過logger2.setLevel(logging.INFO)設置mylogger的日志級別為logging.INFO,所以最后logger1的輸出遵從了后來設置的日志級別。
<2>為什么logger1、logger2對應的每個輸出分別顯示兩次?
這是因為我們通過logger = logging.getLogger()顯示的創建了root Logger,而logger1 = logging.getLogger('mylogger')創建了root Logger的孩子(root.)mylogger,logger2同樣。而孩子,孫子,重孫……既會將消息分發給他的handler進行處理也會傳遞給所有的祖先Logger處理。
ok,那么現在我們把
# logger.addHandler(fh)
# logger.addHandler(ch) 注釋掉,我們再來看效果:
因為我們注釋了logger對象顯示的位置,所以才用了默認方式,即標準輸出方式。因為它的父級沒有設置文件顯示方式,所以在這里只打印了一次。
孩子,孫子,重孫……可逐層繼承來自祖先的日志級別、Handler、Filter設置,也可以通過Logger.setLevel(lel)、Logger.addHandler(hdlr)、Logger.removeHandler(hdlr)、Logger.addFilter(filt)、Logger.removeFilter(filt)。設置自己特別的日志級別、Handler、Filter。若不設置則使用繼承來的值。
<3>Filter
限制只有滿足過濾規則的日志才會輸出。
比如我們定義了filter = logging.Filter('a.b.c'),并將這個Filter添加到了一個Handler上,則使用該Handler的Logger中只有名字帶 a.b.c前綴的Logger才能輸出其日志。
filter = logging.Filter('mylogger')
logger.addFilter(filter)
這是只對logger這個對象進行篩選
如果想對所有的對象進行篩選,則:
filter = logging.Filter('mylogger')
fh.addFilter(filter)
ch.addFilter(filter)
這樣,所有添加fh或者ch的logger對象都會進行篩選。
完整代碼1:
1 importlogging2
3 logger =logging.getLogger()4 #創建一個handler,用于寫入日志文件
5 fh = logging.FileHandler('test.log')6
7 #再創建一個handler,用于輸出到控制臺
8 ch =logging.StreamHandler()9
10 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')11
12 fh.setFormatter(formatter)13 ch.setFormatter(formatter)14
15 #定義一個filter
16 filter = logging.Filter('mylogger')17 fh.addFilter(filter)18 ch.addFilter(filter)19
20 #logger.addFilter(filter)
21 logger.addHandler(fh)22 logger.addHandler(ch)23
24
25
26
27 logger.setLevel(logging.DEBUG)28
29 logger.debug('logger debug message')30 logger.info('logger info message')31 logger.warning('logger warning message')32 logger.error('logger error message')33 logger.critical('logger critical message')34
35 ##################################################
36 logger1 = logging.getLogger('mylogger')37 logger1.setLevel(logging.DEBUG)38
39 logger2 = logging.getLogger('mylogger')40 logger2.setLevel(logging.INFO)41
42 logger1.addHandler(fh)43 logger1.addHandler(ch)44
45 logger2.addHandler(fh)46 logger2.addHandler(ch)47
48 logger1.debug('logger1 debug message')49 logger1.info('logger1 info message')50 logger1.warning('logger1 warning message')51 logger1.error('logger1 error message')52 logger1.critical('logger1 critical message')53
54 logger2.debug('logger2 debug message')55 logger2.info('logger2 info message')56 logger2.warning('logger2 warning message')57 logger2.error('logger2 error message')58 logger2.critical('logger2 critical message')
完整代碼2:
1 #coding:utf-8
2 importlogging3
4 #創建一個logger
5 logger =logging.getLogger()6
7 logger1 = logging.getLogger('mylogger')8 logger1.setLevel(logging.DEBUG)9
10 logger2 = logging.getLogger('mylogger')11 logger2.setLevel(logging.INFO)12
13 logger3 = logging.getLogger('mylogger.child1')14 logger3.setLevel(logging.WARNING)15
16 logger4 = logging.getLogger('mylogger.child1.child2')17 logger4.setLevel(logging.DEBUG)18
19 logger5 = logging.getLogger('mylogger.child1.child2.child3')20 logger5.setLevel(logging.DEBUG)21
22 #創建一個handler,用于寫入日志文件
23 fh = logging.FileHandler('/tmp/test.log')24
25 #再創建一個handler,用于輸出到控制臺
26 ch =logging.StreamHandler()27
28 #定義handler的輸出格式formatter
29 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')30 fh.setFormatter(formatter)31 ch.setFormatter(formatter)32
33 #定義一個filter
34 #filter = logging.Filter('mylogger.child1.child2')
35 #fh.addFilter(filter)
36
37 #給logger添加handler
38 #logger.addFilter(filter)
39 logger.addHandler(fh)40 logger.addHandler(ch)41
42 #logger1.addFilter(filter)
43 logger1.addHandler(fh)44 logger1.addHandler(ch)45
46 logger2.addHandler(fh)47 logger2.addHandler(ch)48
49 #logger3.addFilter(filter)
50 logger3.addHandler(fh)51 logger3.addHandler(ch)52
53 #logger4.addFilter(filter)
54 logger4.addHandler(fh)55 logger4.addHandler(ch)56
57 logger5.addHandler(fh)58 logger5.addHandler(ch)59
60 #記錄一條日志
61 logger.debug('logger debug message')62 logger.info('logger info message')63 logger.warning('logger warning message')64 logger.error('logger error message')65 logger.critical('logger critical message')66
67 logger1.debug('logger1 debug message')68 logger1.info('logger1 info message')69 logger1.warning('logger1 warning message')70 logger1.error('logger1 error message')71 logger1.critical('logger1 critical message')72
73 logger2.debug('logger2 debug message')74 logger2.info('logger2 info message')75 logger2.warning('logger2 warning message')76 logger2.error('logger2 error message')77 logger2.critical('logger2 critical message')78
79 logger3.debug('logger3 debug message')80 logger3.info('logger3 info message')81 logger3.warning('logger3 warning message')82 logger3.error('logger3 error message')83 logger3.critical('logger3 critical message')84
85 logger4.debug('logger4 debug message')86 logger4.info('logger4 info message')87 logger4.warning('logger4 warning message')88 logger4.error('logger4 error message')89 logger4.critical('logger4 critical message')90
91 logger5.debug('logger5 debug message')92 logger5.info('logger5 info message')93 logger5.warning('logger5 warning message')94 logger5.error('logger5 error message')95 logger5.critical('logger5 critical message')
應用:
1 importos2 importtime3 importlogging4 from config importsettings5
6
7 defget_logger(card_num, struct_time):8
9 if struct_time.tm_mday < 23:10 file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon, 22)11 else:12 file_name = "%s_%s_%d" %(struct_time.tm_year, struct_time.tm_mon+1, 22)13
14 file_handler =logging.FileHandler(15 os.path.join(settings.USER_DIR_FOLDER, card_num, 'record', file_name),16 encoding='utf-8'
17 )18 fmt = logging.Formatter(fmt="%(asctime)s : %(message)s")19 file_handler.setFormatter(fmt)20
21 logger1 = logging.Logger('user_logger', level=logging.INFO)22 logger1.addHandler(file_handler)23 return logger1
總結
以上是生活随笔為你收集整理的python第七章_python 第七章 模块的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取数据流_python3+
- 下一篇: mongodb python 大于_Py