##Python之路 Day5 經常使用模塊node
####import 導入模塊python
1.定義git
相似於函數式編程和麪向過程編程,函數式編程則完成一個功能,其餘代碼用來調用便可,提供了代碼的重用性和代碼間的耦合。而對於一個複雜的功能來,可能須要多個函數才能完成(函數又能夠在不一樣的.py文件中),多個.py 文件組成的代碼集合就稱爲模塊,是爲了實現某個功能的代碼集合。
2.導入模塊正則表達式
導入模塊其實就是告訴Python解釋器去解釋那個py文件,導入一個py文件,解釋器解釋該py文件。導入一個包,解釋器解釋該包下的 __init__.py 文件。 導入方法: import module from module.xx.xx import xx from module.xx.xx import xx as rename from module.xx.xx import *
3.模塊的分類算法
模塊有time,datetime表示方式有(1)時間戳,(2)格式化時間字符串,(3)元組(struct_time)共九個元素。shell
時間戳express
>>> time.time() 1550499641.1268253 #打印從19700101 8:00:00到當前時間所經歷的秒數 >>> time.mktime(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X")) 1541662322.0 #將當前時間轉爲時間戳
格式化時間字符串編程
>>> time.ctime(time.time()) 'Mon Feb 18 22:24:59 2019' #接收的參數是字符串 >>> time.asctime(time.localtime()) 'Mon Feb 18 22:25:02 2019' #接收的參數是元組 >>> print(datetime.datetime.now()) 2019-02-18 22:26:41.758610 >>> time.strftime('%X %Y-%m-%d',time.localtime()) '22:33:20 2019-02-18' #根據time.localtime()來自定義時間 >>> print(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X")) time.struct_time(tm_year=2018, tm_mon=11, tm_mday=8, tm_hour=15, tm_min=32, tm_sec=2, tm_wday=3, tm_yday=312, tm_isdst=-1) #將'2018-11-08 15:32:02'轉爲time.localtime()格式,#先後格式須要一一對應可是順序不須要。
元組(struct_time)bash
>>> time.gmtime() #UTC標準時間 time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=14, tm_min=30, tm_sec=32, tm_wday=0, tm_yday=49, tm_isdst=0) >>> time.localtime() #當前時間 time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=22, tm_min=30, tm_sec=36, tm_wday=0, tm_yday=49, tm_isdst=0)
獲取過去或將來時間dom
>>> print(datetime.datetime.now() + datetime.timedelta(3)) 2019-02-21 22:37:31.583559 #三天後時間 >>> print(datetime.datetime.now() + datetime.timedelta(hours=3)) 2019-02-19 01:38:06.303301 #三小時後時間 >>> print(datetime.datetime.now() + datetime.timedelta(hours=-3)) 2019-02-18 19:38:28.503632 #三小時前時間
替換時間
>>> print(datetime.datetime.now().replace(minute=3,hour=2)) 2019-02-18 02:03:08.503691
import random print(random.random()) ##生成0到一之間隨機數 print(random.randint(100,999)) ##生成100到999之間隨機數 print random.randrange(1,10) ##生成1到10之間隨機數,不包含10 print(random.choice([1,'23',[4,5]])) #從列表中返回其中一個值 print(random.uniform(1,3)) ##大於1小於3的小數,如1.927109612082716 print(random.sample('hello',3)) ##從整體序列或集合中選擇多個惟一的隨機元素,以列表形式返回。 item=[1,3,5,7,9] random.shuffle(item) ##打亂item的順序,至關於"洗牌" print(item) import string print(string.ascii_lowercase) ##生成小寫字母 print(string.ascii_uppercase) ##生成大寫字母 print(string.ascii_letters) ##生成全部字母 print(string.digits) ##生成0-9數字 生成隨機驗證碼: import random,string checkcode = '' road=True for i in range(8): if road: checkcode+=random.choice(string.ascii_letters) road=False else: checkcode += random.choice(string.digits) road=True print(checkcode)
提供對操做系統進行調用的接口
import os os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑 os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd os.curdir 返回當前目錄: ('.') os.pardir 獲取當前目錄的父目錄字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 os.removedirs('dirname1') 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 os.mkdir('dirname') 生成單級目錄;至關於shell中mkdir dirname os.rmdir('dirname') 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname os.listdir('dirname') 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 os.remove() 刪除一個文件 os.rename("oldname","newname") 重命名文件/目錄 os.stat('path/filename') 獲取文件/目錄信息 os.sep 輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" os.linesep 輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" os.pathsep 輸出用於分割文件路徑的字符串 os.name 輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' os.system("bash command") 運行shell命令,直接顯示,結果沒法賦值給變量 os.popen("bash command") 執行系統命令,能夠賦值保存可是須要read讀。 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所指向的文件或者目錄的最後修改時間
import shutil shutil.copyfile('1.txt','2.txt') 拷貝文件 shutil.copy('1.txt','2.txt') 拷貝文件和權限 shutil.copy2('1.txt','2.txt') 拷貝文件和權限,還有時間等屬性。 shutil.copymode('f1.log', 'f2.log') 僅拷貝權限。內容、組、用戶均不變,目標文件須要已經存在。 shutil.copystat('f1.log', 'f2.log') 僅拷貝權限和狀態信息訪問時間等。內容、組、用戶均不變,目標文件須要已經存在。 shutil.move('1.txt','2.txt') 移動文件,相同目錄下至關與更名 shutil.copytree(src, dst) 拷貝目錄 shutil.rmtree(path) 刪除目錄 壓縮目錄: shutil.make_archive(base_name, format,...) base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑。 format: 壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」 root_dir: 要壓縮的文件夾路徑(默認當前目錄)壓縮文件。 注:默認會給你的壓縮包加上後綴名。 shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細: import zipfile #壓縮 z=zipfile.ZipFile('test.zip','w') z.write('test.xml') z.write('test1.xml') z.close() #解壓出一個文件 z=zipfile.ZipFile('test.zip','r') z.extract(member='test.xml') z.close() #解壓出全部文件 z=zipfile.ZipFile('test.zip','r') z.extractall(member='test.xml') z.close() import tarfile #壓縮 tar = tarfile.open('your.tar','w') tar.add('test.xml', arcname='test.xml') tar.add('test1.xml', arcname='test1.xml') tar.close() # 解壓 tar = tarfile.open('your.tar','r') tar.extractall() # 可設置解壓地址 tar.close()
####shelve模塊 shelve模塊以k,v格式存儲數據,能夠持久化任何pickle可支持的Python數據類型。
#寫入: d=shelve.open('shelve_test') info={'age':22,'j ob':'it'} name=['zyl','syf','test'] d['in']=info d['na']=name d.close() #讀取例 d=shelve.open('shelve_test') print(d.get('in ')) 結果:{'age': 22, 'j ob': 'it'}
####xml模塊
import xml.etree.ElementTree as ET #讀取: tree = ET.parse('xmltest.xml') root=tree.getroot() for i in root: print(i.tag,i.attrib) ##tag是第一層的標籤名,attrib是第一層標籤名的信息。 for c in i: print(c.tag,c.text,c.attrib) ##打印第二層的標籤名,文本數據,標籤名的信息。 for node in root.iter('year'): print(node.tag,node.text) ##只打印單個節點信息,就算year在多級目錄下也會打印。 #修改: tree = ET.parse('xmltest.xml') root=tree.getroot() for node in root.iter('year'): node.text=str(int(node.text)+1) ##全部標籤爲year的內容加1 node.set("updated",'yes') ##設置標籤屬性。 tree.write('xmltest.xml') ##修改完畢後須要在寫入到文件 刪除某一段: tree = ET.parse('xmltest.xml') root=tree.getroot() for country in root.findall('country'): rank=int(country.find('year').text) if rank == 2012: root.remove(country) #刪除年份爲2012的節點 tree.write('output.xml') 編寫xml文件: new_xml=ET.Element('data') #一級標籤 info=ET.SubElement(new_xml,"personinfo",attrib={'enrolled':'yes'}) #二級標籤 info2=ET.SubElement(new_xml,"personinfo2",attrib={'a':'666'}) #二級標籤 name=ET.SubElement(info,"name") #三級標籤 age=ET.SubElement(info,'age') name.text='zyl' #給三級標籤設置值 age.text='30' name=ET.SubElement(info2,"name") #三級標籤 age=ET.SubElement(info2,'age') name.text='wq' age.text='16' et=ET.ElementTree(new_xml) #生成et對象 et.write('new_xml',encoding="utf-8",xml_declaration=True) #寫入到new_xml文件中
####configparser模塊 用於生成和修改常見配置文檔 生成以下格式:
[Default] a = 1 b = 2 c = 3 forwardx11 = yes [bit] user = hg [topse] port = 5022 forwardx11 = no
若是想用python生成一個這樣的文檔怎麼作呢?
import configparser #編寫文件: config=configparser.ConfigParser() config["Default"]={'a':1, 'b':2, 'c':3} config['bit']={} config['bit']['user']='hg' config['topse']={} a=config['topse'] a['port']='5022' a['forwardx11']='no' config['Default']['ForwardX11']='yes' with open('ConfParser.py','w') as configfile: config.write(configfile) #返回節名稱列表,不包括[DEFAULT]: import configparser config = configparser.ConfigParser() config.read('example.ini') config.sections() #讀取模塊下單獨的選項: import configparser config = configparser.ConfigParser() config.read('example.ini') config['bitbucket.org']['User'] #讀取模塊下選項和對應的參數: >>>print(config.items('bit')) [('user', 'hg')] #只讀取模塊下全部的選項: >>>config.options('bit') ['user'] #刪除單個模塊: config.remove_section('group1') #添加一個模塊: config.add_section('wupeiqi') #給新加的模塊添加一個鍵值對 config.set('wupeiqi','user','zyl') #修改一個選項的值: config.set('group2','k1',11111) #刪除一個選項: config.remove_option('group2','age') #注意:全部修改文件的操做都須要衝新寫入到一個文件中。 config.write(open('ConfParser.py','w'))
####hashlib模塊 用於加密相關的操做,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512,MD5算法
import hashlib #md5: m = hashlib.md5() m.update(b"Hello") ##必須爲bytes格式 m.update(b"It's me") ##多個值會組成一個值,至關於b「Hello It's me」 print(m.digest()) #2進制格式hash print(m.hexdigest()) #16進制格式hash #sha256: m = hashlib.sha512() m.update(b"Hello") print(m.hexdigest()) #加密中文格式: m = hashlib.sha512() m.update("小朱朱".encode(encoding='utf-8')) print(m.hexdigest())
####re模塊 經常使用正則表達式符號
'.' 默認匹配除\n以外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 '^' 匹配字符開頭,若指定flags MULTILINE,這種也能夠匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也能夠 '*' 匹配*號前的字符0次或屢次,re.findall("ab*","cabb3abcbbac") 結果爲['abb', 'ab', 'a'] '+' 匹配前一個字符1次或屢次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb'] '?' 匹配前一個字符1次或0次 '{m}' 匹配前一個字符m次 '{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC' '(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結果 abcabca456c '[]' 匹配其中任意一個字符,也能夠寫爲[a-zA-Z0-9] '[^]' 排除其中全部字符 '\A' 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符結尾,同$ '\d' 匹配數字0-9 '\D' 匹配非數字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t' #flags標誌位 re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同) 例:re.search("([a-z]+)","aaaAaAC234aaa",flags=re.I) S(DOTALL): 點任意匹配模式,改變'.'的行爲,能夠匹配到換行符。 例:re.search(".+","aaaAaAC\r\n234aaa",flags=re.S)
1.re.match函數
嘗試從字符串的起始位置匹配一個模式,若是不是起始位置匹配成功的話,match()就返回none。 語法:re.match(pattern, string, flags=0) #示例: >>> import re >>> obj = re.match('\d+', '123uuasf') >>> print(obj.group()) 123
2.匹配對象方法
1.group() 匹配的整個表達式的字符串 2.group(1) 第一個匹配的()中的值 3.groupdict() 返回以有別名的組的別名爲鍵、以該組截獲的子串爲值的字典 例:print(re.search("(?P<zyl>[0-9]{2})(?P<zz>\d+)","1234567").groupdict()) 結果:{'zyl': '12', 'zz': '34567'} 4.start() 返回匹配開始的位置 5.end() 返回匹配結束的位置 6.span() 返回一個元組包含匹配(開始,結束)的位置
3.re.search方法
掃描整個字符串並返回第一個成功的匹配。 #示例1: >>> print(re.search('com','www.baidu.com').group()) com #示例2: >>> line = "Cats are smarter than dogs"; >>> searchobj=re.search(r'(.*re)(.*)(th.*)',line) ##默認貪婪 >>> print(searchobj.group(2)) smarter
4.re.sub方法
##替換字符串中的匹配項。 語法: re.sub(pattern, repl, string, count=0, flags=0) #示例1: >>> s='2017/19/31' >>> print(re.sub('(\d+)/(\d+)/(\d+)',r'\3-\2-\1',s)) 31-19-2017 #示例2: >>> re.sub("[0-9]+",'|',"aaa234aa111sfaf") 'aaa|aa|sfaf' pattern : 正則中的模式字符串。 repl : 替換的字符串,也可爲一個函數。 string : 要被查找替換的原始字符串。 count : 模式匹配後替換的最大次數,默認0表示替換全部的匹配。
5.findall
在字符串中找到正則表達式所匹配的全部子串,並返回一個列表,若是沒有找到匹配的,則返回空列表.match 和 search 是匹配一次而findall匹配全部。 #示例: >>>print(re.findall('\d+','zul111zyl111')) ['111', '111']
6.split方法
按照可以匹配的子串將字符串分割後返回列表,它的使用形式以下: 語法:re.split(pattern, string[, maxsplit=0, flags=0]) #示例: >>> re.split("[0-9]+","aaa234aa111sfaf") ['aaa', 'aa', 'sfaf'] >>> re.split("([0-9]+)","aaa234aa111sfaf") ['aaa', '234', 'aa', '111', 'sfaf'] #保留分隔符
###每日練習 開發一個簡單的python計算器
1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等相似公式後,必須本身解析裏面的(),+,-,*,/符號和公式(不能調用eval等相似功能偷懶實現),運算後得出結果,結果必須與真實的計算器所得出的結果一致代碼以下
# Author:ZhuYuLiang import re def format_mark(express): express = express.replace('+-', '-') express = express.replace('-+', '-') express = express.replace('++', '+') express = express.replace('--', '+') express = express.replace('*+', '*') express = express.replace('+*', '*') express = express.replace('+/', '/') express = express.replace('/+', '/') return express def Add_and_Sub(value): expr = value sub_expr = re.search(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", expr) if not sub_expr: return expr else: sub_expr2 = sub_expr.group() if len(sub_expr2.split('+')) > 1: n1, n2 = sub_expr2.split('+') result = float(n1) + float(n2) else: n1, n2 = sub_expr2.split('-') result = float(n1) - float(n2) re_sub_expr = re.sub(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", str(result), expr, count=1) bb = Add_and_Sub(str(re_sub_expr)) return bb def Multiplication_and_division(value): expr = value sub_expr = re.search(r"\d+\.?\d*[\/\*]\-?\d+\.?\d*", expr) if not sub_expr: return expr else: sub_expr2 = sub_expr.group() if len(sub_expr2.split('/')) > 1: n1, n2 = sub_expr2.split('/') result = float(n1) / float(n2) elif len(sub_expr2.split('*')) > 1: n1, n2 = sub_expr2.split('*') result = float(n1) * float(n2) else: # 只計算乘除,加減直接pass,放入加減函數執行 pass re_sub_expr = re.sub(r"\d+\.?\d*[/\*]\-?\d+\.?\d*", str(result), expr, count=1) # 反覆調用除法 bb = Multiplication_and_division(format_mark(re_sub_expr)) return bb def compute(value): value=Multiplication_and_division(format_mark(value)) value=Add_and_Sub(format_mark(value)) return value def del_brackets(value): sub_expr=re.search('\([^()]+\)',value) if not sub_expr: return value else: sub_expr=sub_expr.group()[1:-1] sub_expr=compute(sub_expr) sub_expr3 = re.sub('(\([\+\-\*\/\.0-9]+\))', str(sub_expr), value, count=1) delkuohao_expr=del_brackets(format_mark(sub_expr3)) return delkuohao_expr if __name__ == '__main__': while True: express=input('>>: ').replace(' ','') print('eval輸出值: ',eval(express)) if not express: continue elif express == 'q': exit() elif re.search('[^0-9.+\-*/()]',express): print('\033[31;1m輸入錯誤\033[0m') else: express=del_brackets(express) express2 = compute(format_mark(express)) print('公式輸出值: ',express2)