一,python的模塊node
Python 模塊(Module),是一個 Python 文件,以 .py 結尾,包含了 Python 對象定義和Python語句。python
模塊讓你可以有邏輯地組織你的 Python 代碼段。linux
把相關的代碼分配到一個模塊裏能讓你的代碼更好用,更易懂。web
模塊能定義函數,類和變量,模塊裏也能包含可執行的代碼正則表達式
模塊一共有三種算法
新建一個python包,名稱爲day21_lesson和文件夾不一樣的是包裏面包含__init__.py文件shell
新建兩個py文件 test.py和cal.py編程
cal.pyjson
def add(x,y): return x + y def sub(x,y): return x - y
test.pyapp
import cal print(cal.add(5,3)) 8
PS:調用須要在前面加模塊名在家對應定義的函數名
使用Pycharm調用cal時候會標紅,可是執行不會報錯
import操做
1,執行對應文件(假如裏面有print會先打印出對應內容 只是實際不會這樣去操做)
2,引入變量 (函數也是一個變量)
若是不想加模塊名調用函數
#import cal from cal import add from cal import sub print(add(5,3)) print(sub(5,3))
8
2
若是有多個則使用* (不推薦這樣調用,由於邏輯函數裏面也可能會定義函數可能會重名,若是遇到重複的會按照順序那個定義在最後就是那個有效)
#import cal from cal import * print(add(5,3)) print(sub(5,3)) 8 2
PS:使用from cal import sub這種調入方式仍是會執行cal.py裏面全部的代碼,而後把對應的變量調用過來
調用模塊首先從調用模塊的執行文件路徑下面找模塊,其次從默認的路徑找模塊
使用sys.path能夠調出使用默認模塊的路徑,第一個就是執行文件的本地路徑
import sys print(sys.path) ['D:\\blzfmima\\python3_s3\\day21\\day21_lesson', 'D:\\blzfmima\\python3_s3', 'D:\\blzfmima\\python3_s3\\venv\\Scripts\\python35.zip', 'D:\\blzfmima\\python3_s3\\venv\\DLLs', 'D:\\blzfmima\\python3_s3\\venv\\lib', 'D:\\blzfmima\\python3_s3\\venv\\Scripts', 'C:\\Python35\\Lib', 'C:\\Python35\\DLLs', 'D:\\blzfmima\\python3_s3\\venv', 'D:\\blzfmima\\python3_s3\\venv\\lib\\site-packages', 'C:\\Program Files\\JetBrains\\PyCharm 2017.3.1\\helpers\\pycharm_matplotlib_backend']
在執行文件test.py在新建一個python包 把對應的模塊文件放入裏面
調用的方式不同 從my_module裏面調用cal
from my_module import cal print(cal.add(1,3))
是從執行文件的路徑下面開始尋找調用的模塊,假如文件路徑是這樣
bin.py是程序入口文件
from my_module import main main.run()
main.py是主程序文件(雖然main.py和調用的模塊cal是同一文件夾下面可是這裏不能使用import cal調用,由於本次的程序入口文件是bin.py因此這裏main調用也必須從該入口文件開始)
#import cal
from my_module import cal def run(): print(cal.add(5,3))
PS:若是必定想要使用import調用能夠經過append方法把cal的路徑添加到sys.path
多層引用模塊使用.來分割
from web.web1.web2 import cal print(cal.add(5,3)) 8
PS:import調用的是py文件 若是調用文件夾運行不會報錯會執行對應的的包下面的__init__.py文件
假如在__init__.py文件寫入語句import . cal 也能夠執行 ,不建議這樣使用
變量__name__ 在執行文件裏面__name__的值爲 __main__ 在調用文件裏面打印的是調用函數的路徑,若是在cal裏面加入print(__name__)使用其餘的文件調用出現的值爲web.web1.web2.cal
使用if __name__=='__main__'進行判斷的做用
1,放在被調用的文件裏面用於測試
2,放在執行文件裏面不想被其餘文件調用
二,python內置模塊
1,time時間模塊
time.py
import time #時間戳 (用於計算) print(time.time()) #1516937562.8488374秒從1970年1月1日0時0分0秒開始算起的時間秒 #結構化時間 使用localtime取到一個時間對象,能夠經過時間對象取值 print(time.localtime()) #time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=11, tm_min=46, tm_sec=4, tm_wday=4, tm_yday=26, tm_isdst=0) t = time.localtime() #根據時間對象取年及星期的第幾天,星期一是0 打印爲4表明星期五 print(t.tm_year) print(t.tm_wday) #---- #和localtime同樣可是tm_hours少了8個小時是和格林尼治時間的對比,是世界標準時間 print(time.gmtime()) #time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=3, tm_min=46, tm_sec=4, tm_wday=4, tm_yday=26, tm_isdst=0) #字符串時間 #把時間戳轉換成結構化時間struct_time print(time.localtime(1431242343)) #time.struct_time(tm_year=2015, tm_mon=5, tm_mday=10, tm_hour=15, tm_min=19, tm_sec=3, tm_wday=6, tm_yday=130, tm_isdst=0) #將結構化時間轉換成時間戳 print(time.mktime(time.localtime())) #1516946698.0 #把結構化時間轉換成字符串的時間 %X代指時分秒 print(time.strftime('%Y-%m-%d %X',time.localtime())) #2018-01-26 #把字符串是時間裝換成結構化時間(須要嚴格一一對應包括之間的空格及-符號,不然報錯) print(time.strptime('2018-01-26 14:13:32','%Y-%m-%d %X')) #time.struct_time(tm_year=2018, tm_mon=1, tm_mday=26, tm_hour=14, tm_min=13, tm_sec=32, tm_wday=4, tm_yday=26, tm_isdst=-1) #asctime把一個時間元祖或者struct_time表示爲固定的字符串時間格式,若是沒有傳遞參數默認傳遞time.localtime() print(time.asctime()) #Fri Jan 26 14:34:10 2018 #把一個時間戳轉換成time.asctime()的形式,若是沒有傳遞參數默認使用time.time() print(time.ctime()) #Fri Jan 26 14:34:10 2018 #time.sleep()推遲運行時間參數爲秒 time.sleep(1) #另一個時間模塊datatime 打印的時間更加符合咱們需求 import datetime print(datetime.datetime.now())
關於時間模塊的轉換圖示
2,random模塊
隨機模塊.py
尾部付一個生成帶字母和數字的字符串
import random #生成一個0-1之間的隨機浮點數 ret = random.random() print(ret) #0.06990352689202717 #生成一個區間的整數1,2,3 print(random.randint(1,3)) #[1,3] #生成一個區間的整數不取最右邊的1,2 print(random.randrange(1,3)) #[1,3) #從一個可迭代對象裏面隨機選取一個元素 print(random.choice([11,22,33])) #[11,22,33] #從一個可迭代對象裏面隨機選取幾個元素 選兩個生成一個列表 print(random.sample([11,22,33],2)) #生成一個範圍內發浮點型 print(random.uniform(1,3)) #隨機打亂順序(不經常使用) item = [1,2,3,4,5] #打亂順序修改原表,沒有返回值 random.shuffle(item) print(item) #[4, 1, 2, 5, 3] 也多是其餘的順序 #寫一個驗證碼函數 def v_code(): #定義一個字符串接收驗證碼 ret = '' for i in range(4): #生成一個隨機數字 num = random.randint(0,9) #生成兩個隨機字母 alf1是隨機大寫字母 alf2是隨機小寫字母 alf1 = chr(random.randint(65,90)) alf2 = chr(random.randint(97,122)) #從兩個隨機字母中挑選一個 alf = random.choice([alf1,alf2]) #從數字或者字母中隨機挑選一個 s = str(random.choice([num,alf])) #拼接而後做爲返回值返回 ret += s return ret res = v_code() print(res)
2,os模塊
os_test.py
import os #getcwd獲取當前工做目錄 print(os.getcwd()) #D:\blzfmima\python3_s3\day22 #chdir改變工做目錄至關於linux裏面的cd #能夠是絕對路徑也能夠是當前目錄的相對路徑 #os.chdir('test1') print(os.getcwd()) #D:\blzfmima\python3_s3\day22\test1 #curdir獲取當前目錄字符串名 print(os.curdir) #. #pardir獲取當前目錄的父目錄字符串名 print(os.pardir) #.. #makedirs生成多層遞歸目錄新建兩個文件夾其中dirname1和本文件同目錄dirname2在dirname1的下一級目錄 #至關於linux裏面的mkdir -p命令 #os.makedirs('dirname1/dirname2') #removedirs若目錄爲空則刪除,並遞歸到上一級目錄,若是也爲空則刪除,以此類推 #os.removedirs('dirname1/dirname2') #mkdir生成單級目錄至關於linux裏面的mkdir #os.mkdir('dirname') #rmdir刪除單級目錄若是不爲空則報錯 #os.remove('dirname') #listdir列出指定目錄下面的全部文件和子目錄,包括隱藏文件,並以列表的方式打印 #只列出一級目錄 print(os.listdir()) #['dirname', 'os_test.py', 'test1'] #rename修改文件名 #os.rename('oldname','newname') #stat列出對應文件的信息包括文件大小,建立時間修改時間等 print(os.stat('sss.py')) #os.stat_result(st_mode=33206, st_ino=281474976879558, st_dev=1010701401, st_nlink=1, st_uid=0, st_gid=0, st_size=11, st_atime=1517191298, st_mtime=1517191298, st_ctime=1517191298) #sep輸出操做系統特定路徑分隔符 win下爲'\\' linux爲'/' print(os.sep) # \ #linesep輸出當前平臺使用的行終止符 win下爲'\r\n' linux下爲'\n' print(os.linesep) #pathsep輸出用於分割文件路徑的字符串 win下爲; linux下爲: print(os.pathsep) # ; #name輸出字符串指示當前使用平臺 win爲'nt' linux爲'posix' print(os.name) #nt #system 運行shell命令直接顯示 #os.system('ipcofig') #split 將path分割成目錄和文件名的二元組返回 print(os.path.split(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #('D:/blzfmima/python3_s3/day21/day21_lesson/bin', 'bin.py') #dirname返回path目錄,其實就是os.path.split(path)的第一個元素 print(os.path.dirname(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #D:/blzfmima/python3_s3/day21/day21_lesson/bin #basename返回path最後的文件名若是以/或者\結尾那麼會返回空值,及os.path.split(path)的第二個元素 print(os.path.basename(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #bin.py #exists若是path存在返回True不然返回False print(os.path.exists(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #True #isabs若是是絕對路徑返回True print(os.path.isabs(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #True #iffile是否是一個文件是文件返回True print(os.path.isfile(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #True #isdir是不是一個存在的目錄返回True print(os.path.isdir(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin')) #True #join將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 a = 'D:/blzfmima/python3_s3' b = 'day21/day21_lesson/bin/bin.py' print(os.path.join(a,b)) #D:/blzfmima/python3_s3\day21/day21_lesson/bin/bin.py #getatime返回path所指向的文件或者目錄的最後存取時間 print(os.path.getatime(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #getmtime返回path所指向的文件或者目錄的最後修改時間 print(os.path.getmtime(r'D:/blzfmima/python3_s3/day21/day21_lesson/bin/bin.py')) #environ獲取系統環境變量 print(os.environ)
3,sys模塊
#print(sys.version) #3.5.2rc1 (v3.5.2rc1:68feec6488b2+, Jun 12 2016, 08:56:24) [MSC v.1900 64 bit (AMD64)] #path返回模塊搜索路徑 #print(sys.path) #platform返回操做系統平臺名稱 #print(sys.platform) #win32 或者linux #stdout.write寫進度條 import time for i in range(10): sys.stdout.write("#") time.sleep(0.1) sys.stdout.flush()
4,json模塊
以前咱們學習過用eval內置方法能夠將一個字符串轉換成python對象,不過,eval方法是有侷限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時間,eval就無論用了,因此eval的字典仍是一般用來執行一個字符串表達式,並返回表達式的值
json_test.py
import json dic = {'name':'zhangsan'} dic_str = json.dumps(dic) print(dic_str) #{"name": "zhangsan"} print(type(dic_str)) #<class 'str'> #打開如下新文件把通過json.dumps轉換後的字符串{"name": "zhangsan"}寫入文件 with open('new_hello','w') as f_write: f_write.write(dic_str) #以只讀方式打開文件而且使用json.loads方法把字符串轉換成對應的數據類型爲dict with open('new_hello','r') as f_read: data = json.loads(f_read.read()) print(data) print(type(data)) {"name": "zhangsan"} <class 'str'> {'name': 'zhangsan'} <class 'dict'>
PS:字符串不必定須要先dumps以後才能loads字符串只要符合json規範便可loads
5,pickle模塊
pickle_test.py
import pickle dic = {'name':'zhangsan'} j = pickle.dumps(dic) #使用pickle序列化 生成的對象是不可直接讀的,讀取是亂碼 #只能使用pickle反序列化 f = open('序列號對象_pickle','wb') f.write(j) #等價與pickle.dump(dic,f) f.close() #反序列化 f = open('序列號對象_pickle','rb') data = pickle.loads(f.read()) f.close() print(data['name']) zhangsan
PS:pickle可序列化的數據類型比json多,能夠序列化函數,類。可是這種需求較少,通常直接使用json便可
5,shelve模塊(不經常使用瞭解便可)
shelve模塊比pickle模塊簡單,只有一個open函數,返回相似字典的對象,可讀可寫;key必須爲字符串,而值是python所支持的數據類型
shelve_test.py
import shelve #f = shelve.open(r'shelve1') #目的:將一根字典放入文本 #f['stu1_info'] = {'name':'zhangsan','age':18} #f['stu2_info'] = {'name':'lisi','age':28} #f['school_info'] = {'website':'edu.com','city':'shenzhen'} #f.close() f = shelve.open(r'shelve1') print(f.get('stu1_info')['age'])
先使用shelve方法把字典寫入三個文件(不可讀亂碼),而後使用get方法取值
6,xml模塊
xml是實現不一樣語言和程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單。
列子測試xml文檔 xml_lesson
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year updated="yes">2012</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year updated="yes">2015</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year updated="yes">2015</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
對xml文件進行操做xml_test.py
#使用as能夠把比較長的模塊簡寫 import xml.etree.ElementTree as ET #使用parse解析後賦值給tree對象 tree = ET.parse("xml_lesson") #getroot拿到跟節點 root = tree.getroot() print(root.tag) #data # for i in root: # #print(i.tag) # #print(i.attrib) # #print(i.text) # for j in i: # print(j.tag,j.text) # 遍歷xml文檔 # # # 只遍歷year 節點 # for node in root.iter('year'): # print(node.tag, node.text) # # --------------------------------------- # # import xml.etree.ElementTree as ET # # tree = ET.parse("xmltest.xml") # root = tree.getroot() # # # 修改 for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated", "yes") #修改後寫進去文件名能夠重複則覆蓋,也能夠不重複則新建一個文件 tree.write("xml_lesson") # # # 刪除node for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')
生成xml文檔xml_create.py
import xml.etree.ElementTree as ET new_xml = ET.Element("namelist") name = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) age = ET.SubElement(name, "age", attrib={"checked": "no"}) sex = ET.SubElement(name, "sex") sex.text = '33' name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "no"}) age = ET.SubElement(name2, "age") age.text = '19' et = ET.ElementTree(new_xml) # 生成文檔對象 et.write("test.xml", encoding="utf-8", xml_declaration=True) ET.dump(new_xml) # 打印生成的格式
7,re模塊
就期本質而言,正則表達式(re)是一種小型的,高度專業化的編程語言,在python中它內嵌在python中經過re模塊實現。
一,re模塊的匹配規則及元字符
re_lesson.py
import re #徹底匹配若是須要匹配的字符串中間包含其餘字符就匹配不到 ret = re.findall('zhangsan','hellozhangsan') print(ret) #['zhangsan'] #元字符 .^$+?{}[]|()\ #.通配符能夠匹配一個任何字符,沒有匹配到返回一個空列表 ret = re.findall('m..g','yueming') print(ret) #['ming'] #^以什麼開頭的 ret = re.findall('^y.e','yueming') print(ret) #['yue'] #$以什麼結尾的 ret = re.findall('ing$','yuming') print(ret) #['ing'] #*表明匹配0次到無窮次 ret = re.findall('d*','sfdgsdddddd') print(ret) #['', '', 'd', '', '', 'dddddd', ''] #+表明匹配1到無窮次 ret = re.findall('d+','sfdgsdddddd') print(ret) #['d', 'dddddd'] #? 匹配0或者1次 ret = re.findall('ming?','asdhfaming') print(ret) #ming #{}本身定義匹配多少 {0,} == * 0到無窮至關於* # {1,} == + 1到無窮至關於+ # {0,1} == ? 0或者1至關於? # {6} 重複6次 {1,6}能夠重複1到6次之間的任何次數 ret = re.findall('ming{0,}','yuemingg') print(ret) #['mingg'] ret = re.findall('ming{1,}','yueminggg') print(ret) #['minggg'] ret = re.findall('ming{0,1}','yuemin') print(ret) #['min'] #PS:默認都是貪婪匹配儘量多地取匹配若是須要惰性匹配在後面加一個? 以下 ret = re.findall('ming{1,}?','yueminggg') print(ret) #['ming'] #[]字符集 #起到或的做用 ret = re.findall('x[yz]p','xypuuuxzp') print(ret) #使用-表明一個區間 ret = re.findall('[a-z1-9]','abbh1210') print(ret) #['a', 'b', 'b', 'h', '1', '2', '1'] #PS:在字符集[]裏面除了 - ^ \ 其餘的均爲普通字符 #^放在字符集裏面不是匹配開頭而是非 ret = re.findall('q[^a-z]','qa') print(ret) #[] #計算器思路,匹配兩個括號中間沒有括號的任意字符 #前面\(表明匹配左括號 後面\)表明匹配右括號 #[^()]表明中間沒有括號 這裏的()由於是在[]裏面不須要加\轉義 #*表明匹配兩個()之間的任意字符 #這樣就能取出一個任意長計算字符串最裏面括號的那一串字符了 ret = re.findall('\([^()]*\)','12+(34*6+2-5*(2-1))') print(ret) #['(2-1)'] #元字符之轉義字符\ #反斜槓後面跟元字符去除特殊功能,好比\.就表明字符. #反斜槓後面跟普通字符實現特殊功能,好比\d #\d匹配任何十進制數,至關於[0-9] ret = re.findall('\d','asad12asd2') print(ret) #['1', '2', '2'] #\D匹配任意非數字字符,至關於[^0-9] ret = re.findall('\D+','asad12asd2') print(ret) #['asad', 'asd'] #\s匹配任意空白字符,至關於於[\t\n\r\f\v] ret = re.findall('\s+','hello world') print(ret) #\S匹配任意非空白字符,至關於[^\t\n\r\f\v] ret = re.findall('\S+','hello world') print(ret) #\s和\S不經常使用 #\w匹配任意字母數字字符包括下劃線,至關於[a-zA-Z0-9_] ret = re.findall('\w+','hello world') print(ret) #['hello', 'world'] #\W匹配任意非字母數字字符,至關於[^a-zA-Z0-9] ret = re.findall('\W+','hello world#') print(ret) #[' ', '#'] #使用\去除特殊符號的特殊功能 ret = re.findall('www\*baidu','www*baidu.com') print(ret) #\b匹配一個特殊邊界字符,好比空格 & #等 #需求匹配單獨的I #這裏須要在\b前面在加一個\再次轉義 或者在前面加r表明裏面的字符串不作任何轉義 #\\表明把\轉義爲普通的字符\ 在加上b就表明能夠匹配空格了 #由於\b不光在re裏面有意義一樣在python裏面也是有意義的 #\b在python裏面的意義表明是退格 #print('123\b')輸出爲12 原本應該輸出的3被退格了 ret = re.findall('I\b','hello I am LIST') print(ret) #需求匹配\f #python調用模塊re裏面也有本身的語法及轉義字符 #這裏須要加4個\ 由於\\在python裏面轉義表明一個\ #若是re模塊接收到2個\ 轉義一下就表明一個普通的\了 ret = re.findall('c\\\\l','abc\le') print(ret) #元字符之| 或匹配 ret = re.findall('ka|b','kajkb') print(ret) #['ka', 'b'] ret = re.findall('(?P<name>\w+)','abcabc') print(ret) #search方法 只取第一個知足條件的 返回的是一個對象 #沒有找到返回爲空 ret = re.search('\d+','sdasd34sdf13') print(ret) #<_sre.SRE_Match object; span=(5, 7), match='34'> #經過group方法返回對象的結果 print(ret.group()) #34 ret = re.search('(?P<name>[a-z]+)','123asdf43') print(ret.group()) #asdf #?P<name>經過分組取對應的信息假設前面是姓名後面是對應的年齡信息 #分組可用於提取url信息 ret = re.search('(?P<name>[a-z]+)\d+','zhangsan16lisi18') print(ret.group()) #zhangsan16 print(ret.group('name')) #zhansan #一樣年齡也能夠分一個組爲id ret = re.search('(?P<name>[a-z]+)(?P<id>\d+)','zhangsan16lisi18') print(ret.group('name')) #zhangsan print(ret.group('id')) #16
二,re模塊的方法
re_method.py
import re #findall 返回全部知足條件的結果,放在一個列表裏面,沒有結果返回空列表 ret = re.findall('a','abc') print(ret) #['a'] #search匹配,只找到第一個匹配返回一個對象 #經過group()方法取得字符串,若是沒有匹配返回爲空 ret = re.search('a','abc') print(ret) #<_sre.SRE_Match object; span=(0, 1), match='a'> print(ret.group()) #a #match同search 不一樣之處在於match從字符串開始匹配 #至關於使用search匹配加了一個^ ret = re.match('\d+','asda12') print(ret) #None ret = re.match('\d+','12asda12') print(ret) #<_sre.SRE_Match object; span=(0, 2), match='12'> #split分割 #使用空格分割 ret = re.split(' ','hello abc') print(ret) #['hello', 'abc'] #使用[]能夠定義多個分割符號 ret = re.split('[ |]','hello abc|def') print(ret) #['hello', 'abc', 'def'] #分割過程 #1,用a分割由於a左邊沒有及爲空分割後爲['','bc'] #2,用b分割既成['', '','c'] ret = re.split('[ab]','abc') print(ret) #['', '','c'] #sub替換 #三個參數,源 目標 字符串 #這裏使用b替換a ret = re.sub('a','b','abc') print(ret) #bbc #默認是所有匹配,後面加參數指定匹配次數(使用機率小) ret = re.sub('\d','A','abc1212324asfd',4) print(ret) #abcAAAA324asfd #subn把匹配的次數打印出來 ret = re.subn('\d','A','abc1212324asfd',4) print(ret) #('abcAAAA324asfd', 4) #compile把匹配規則編譯生成一個對象 #調用該對象就是直接使用規則,跟的參數就只有須要匹配的字符串便可 #做用定義匹配規則能夠屢次調用 com = re.compile('\d+') print(com) #re.compile('\\d+') ret = com.findall('ad12') print(ret) #['12'] #finditer 同findall效果同樣 可是返回的是一個迭代器對象不是一個列表 ret = re.finditer('\d','asdasd71623asdjhagsd') print(ret) #<callable_iterator object at 0x0000022D562C7240> #使用for循環加group方法能夠取出結果 for item in ret: print(item.group())
PS:使用()分組的優先級
ret = re.findall('www\.(baidu|163)\.com','www.baidu.com') print(ret) #['baidu']
由於使用了()分組 已經匹配到www.baidu.com可是默認優先級是取()裏面的因此這裏的結果是['baidu']
在分組()裏面的前面加?:去除分組優先級
ret = re.findall('www\.(?:baidu|163)\.com','www.baidu.com') print(ret) ['www.baidu.com']
分組()補充
#分組()補充 ret = re.findall('(abc)+','abcabcabc') print(ret) #輸出以下,由於優先匹配一個()內裏面的內容 #['abc'] ret = re.findall('(?:abc)+','abcabcabcdsdabc') print(ret) #加?:取消優先級輸出以下 #['abcabcabc', 'abc']
8,logging模塊(重要)
日誌模塊,記錄信息
一,簡單應用
logging_test.py
import logging #默認只打印warning以上信息設置成debug能夠打印全部信息 logging.basicConfig( level=logging.DEBUG, #默認是把日誌顯示在屏幕上,下面定義寫入文件 #寫入文件是追加,原內容不變 filename="logger.log", #如下參數設置爲覆蓋 #filemode='w', #定義日誌格式 #asctime時間 #filename執行文件的名稱這裏是logging_test.py #lineno行號 #message自定義的信息 format='%(asctime)s %(filename)s [%(lineno)d] %(message)s' ) logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') #root是默認的用戶名 ''' DEBUG:root:debug message INFO:root:info message WARNING:root:warning message ERROR:root:error message CRITICAL:root:critical message '''
二,使用logger對象把日誌信息寫入到文件的同時顯示到屏幕
logging_test2.py
import logging #logger對象,使日誌既顯示的屏幕又輸出到文件 logger=logging.getLogger() #建立實例化對象能夠向文件發送內容 fh=logging.FileHandler("test.log") #建立實例化對象能夠向屏幕發送內容 ch=logging.StreamHandler() #自定義日誌格式 fm=logging.Formatter("%(asctime)s %(message)s") #使用fh和ch吃掉日誌格式fm fh.setFormatter(fm) ch.setFormatter(fm) #使用logger分別吃掉fh和ch logger.addHandler(fh) logger.addHandler(ch) #設置日誌級別 logger.setLevel("DEBUG") #----------------------->> logger.debug("debug message") logger.info("info message") logger.warning("warning message") logger.error("error message") logger.critical("critical message")
PS:logger對象使用比basicConfig更多
再看一個列子logging_test3.py
import logging ################################################## #默認是root跟用戶加參數設置子用戶 logger1 = logging.getLogger('mylogger') logger1.setLevel(logging.DEBUG) logger2 = logging.getLogger('mylogger') logger2.setLevel(logging.INFO) #建立實例化對象能夠向文件發送內容 fh=logging.FileHandler("test_new.log") #建立實例化對象能夠向屏幕發送內容 ch=logging.StreamHandler() logger1.addHandler(fh) logger1.addHandler(ch) logger2.addHandler(fh) logger2.addHandler(ch) logger1.debug('logger1 debug message') logger1.info('logger1 info message') logger1.warning('logger1 warning message') logger1.error('logger1 error message') logger1.critical('logger1 critical message') logger2.debug('logger2 debug message') logger2.info('logger2 info message') logger2.warning('logger2 warning message') logger2.error('logger2 error message') logger2.critical('logger2 critical message')
咱們明明經過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的輸出聽從了後來設置的日誌級別。
再看一個列子
logging_test4.py
import logging ################################################## #默認是root跟用戶加參數設置子用戶 logger1 = logging.getLogger('mylogger') logger1.setLevel(logging.DEBUG) logger2 = logging.getLogger('mylogger') logger2.setLevel(logging.INFO) #建立實例化對象能夠向文件發送內容 fh=logging.FileHandler("test_new.log") #建立實例化對象能夠向屏幕發送內容 ch=logging.StreamHandler() logger1.addHandler(fh) logger1.addHandler(ch) logger2.addHandler(fh) logger2.addHandler(ch) logger=logging.getLogger() logger.addHandler(ch) logger.addHandler(fh) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message') logger1.debug('logger1 debug message') logger1.info('logger1 info message') logger1.warning('logger1 warning message') logger1.error('logger1 error message') logger1.critical('logger1 critical message')
PS:子對象logger1會重複打印兩次,由於子在打印的時候回找父若是存在就多打印一次(知道便可,用的較少)
9,configparser模塊
配置文件解析模塊
生成配置文件 config.py
import configparser #建立一個生產配置文件的實例化對象 #有了這個對象至關於有一個空字典{} config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'} config['bitbucket.org'] = {} config['bitbucket.org']['User'] = 'hg' config['topsecret.server.com'] = {} topsecret = config['topsecret.server.com'] topsecret['Host Port'] = '50022' # mutates the parser topsecret['ForwardX11'] = 'no' # same here config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as configfile: #寫入的方式會普通打開文件寫入的方式不一樣 config.write(configfile)
生成的配置文件example.ini
[DEFAULT] compression = yes serveraliveinterval = 45 compressionlevel = 9 forwardx11 = yes [bitbucket.org] user = hg [topsecret.server.com] host port = 50022 forwardx11 = no
對配置文件增刪改查confile2.py
import configparser config = configparser.ConfigParser() #---------------------------------------------查 #未讀取配置文件,爲空 print(config.sections()) #[] #讀取配置文件 config.read('example.ini') #默認的不打印,只打印默認之外的塊名 print(config.sections()) #['bitbucket.org', 'topsecret.server.com'] #判斷對應的塊是否在配置文件裏面 print('bytebong.com' in config)# False #取出塊下面的某一個值,這裏裏面不區分大小寫 print(config['bitbucket.org']['User']) # hg print(config['DEFAULT']['Compression']) #yes print(config['topsecret.server.com']['ForwardX11']) #no #遍歷對應的模塊下面的鍵 #會默認把default下面的鍵都遍歷處理 for key in config['bitbucket.org']: print(key) # user # serveraliveinterval # compression # compressionlevel # forwardx11 #options把鍵取出來生成一個列表 print(config.options('bitbucket.org'))#['user', 'serveraliveinterval', 'compression', 'compressionlevel', 'forwardx11'] #items取出key和value組成元祖再放在列表裏面 print(config.items('bitbucket.org')) #[('serveraliveinterval', '45'), ('compression', 'yes'), ('compressionlevel', '9'), ('forwardx11', 'yes'), ('user', 'hg')] #取對應模塊下面對應的鍵對應的值 #這裏bitbucket.org下面是沒有compression這個鍵的 #可是去默認default下面有,就取到了對應的鍵值爲yes print(config.get('bitbucket.org','compression'))#yes #---------------------------------------------刪,改,增(config.write(open('i.cfg', "w"))) #增長一個yuan的塊 config.add_section('yuan') #移除topsecret.server.com塊 config.remove_section('topsecret.server.com') #移除塊bitbucket.org下面的鍵值爲user的配置 config.remove_option('bitbucket.org','user') #在塊bitbucket.org下面新建一個鍵爲k1鍵值爲1111的配置 config.set('bitbucket.org','k1','11111') #修改成寫到一個新的文件 #使用open('i.cfg', "w")代替 with open('i.cfg','w') as f: #能夠這樣寫,不須要關閉 config.write(open('i.cfg', "w"))
生成的新文件i.cfg
[DEFAULT] compression = yes serveraliveinterval = 45 compressionlevel = 9 forwardx11 = yes [bitbucket.org] k1 = 11111 [yuan]
10,hashlib模塊
用於加密相關操做,3.x裏代替了md5模塊和sha模塊,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5算法
hashlib_test.py
import hashlib obj=hashlib.md5() obj.update("admin".encode('utf8')) print(obj.hexdigest()) #5d41402abc4b2a76b9719d911017c592 #這一步是在字符串admin基礎上作的,至關於對字符串'adminroot'加密 obj.update('root'.encode('utf8')) print(obj.hexdigest()) #4b3626865dc6d5cfe1c60b855e68634a #sha256和md5用法是同樣的 m = hashlib.sha256() m.update('admin'.encode('utf8')) print(m.hexdigest()) #8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918