python模組常用用法
1、time模組(※※※※)
import time #匯入時間模組 print(time.time()) #返回當前時間的時間戳,可用於計算程式執行時間 print(time.localtime()) #返回當地時間的結構化時間格式,引數預設為時間戳 print(time.gmtime) #返回UTC時間的結構化時間格式 print(time.mktime(time.localtime())) #將結構化時間轉換為時間戳 print(time.strftime("%Y-%m-%d %X",time.localtime())) #將結構化時間轉換為字串時間 print(time.strptime("2019:9:30:12:55:36","%Y:%m:%d:%X")) #將字串時間轉換為結構化時間 print(time.asctime()) #將結構化時間或表示時間的元組轉換為'Sun Jun 20 23:21:05 1993'的格式 print(time.ctime()) #將時間戳轉換為time.asctime格式,預設time.time為引數
PS:由於平時習慣,strftime比較常用,strptime和它是反操作,下列方法輸出格式能更符合人們的習慣
import datetime #匯入datetime模組 print(datetime.datetime.now()) #輸出2019-09-30 15:15:09.562809的格式
2、random模組(※※)
import random print(random.random()) #返回0到1之間的隨機浮點數 print(random.randint(1,3)) #返回1到3之間的隨機整數,包括3 print(random.randrange(1,3)) #返回1到3之間的隨機整數,不包括3 print(random.choice([1,'23',[4,5]])) #隨機返回列表中一個數據 print(random.sample([1,'23',[4,5]],2)) #隨機返回列表中兩個資料 print(random.uniform(1,3)) #返回1到3之間的浮點數 item=[1,3,5,7,9] random.shuffle(item) print(item) #把item列表打亂
3、os模組(※※※※)
import os os.getcwd() #返回當前指令碼工作目錄路徑 os.chdir("dirname") #改變當前指令碼工作目錄 os.makedirs('dirname1/dirname2') #生成多層遞迴目錄 os.removedirs('dirname1') #若目錄為空則刪除,並遞迴到上一級目錄,若也為空則繼續刪除,依此類推 os.mkdir('dirname') #生成單級目錄 os.rmdir('dirname') #刪除單級空目錄,若目錄不為空則無法刪除並報錯 os.listdir('dirname') #以列表方式返回指定目錄下的所有檔案和子目錄,包括隱藏檔案 os.remove() #刪除一個檔案 os.rename("oldname","newname") #重新命名檔案或目錄 os.stat('path/filename') #獲取檔案或目錄 os.linesep #輸出當前平臺使用的行終止符(win下為"\r\n",Linux下為"\n") os.pathsep #輸出用於分割檔案路徑的字串(win下為;,Linux下為:) os.path.abspath(path) #返回path規範化的絕對路徑 os.path.split(path) #返回path分割成的目錄和檔名二元組 os.path.dirname(path) #返回path的目錄 os.path.basename(path) #返回path的檔名,若path以/或\結尾則返回空值 os.path.exists(path) #path存在返回True,不存在則返回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指向的檔案或者目錄最後修改時間
PS:其中os.path.join較為常用。
4、sys模組(※※※)
import sys sys.argv #命令列引數List,第一個元素是程式本身路徑 sys.exit(n) #退出程式,正常退出時exit(0) sys.version #獲取Python解釋程式的版本資訊 sys.maxint #最大的Int值 sys.path #返回模組的搜尋路徑,初始化時使用PYTHONPATH環境變數的值 sys.platform #返回作業系統平臺名稱
PS:其中sys.argv較為常用,下面程式碼實現進度條的列印,使用flush重新整理螢幕列印
import sys,time for i in range(100): sys.stdout.write('#') time.sleep(1) sys.stdout.flush()
5、json&pickle(※※※※)
import json dic={'name':'alvin','age':23,'sex':'male'} #定義一個字典,為字典格式 f=open('序列化物件','w') j=json.dumps(dic) #把字典序列化,即單引號變雙引號,然後再在最外面加單引或雙引變成所有程式語言都可用的字串格式 f.write(j) #也可以用dump用法,這兩行則等價於json.dump(dic,f) f.close() f=open('序列化物件') data=json.loads(f.read()) #把字串反序列化,即把字串格式變成字典格式,也可以用load用法,這兩行則等價於data=json.load(f)
PS:dump和load用法更加簡潔,但是僅限於檔案操作,所以還是推薦dumps和loads。另外dumps和loads不是一定要連用,只要字串滿足dumps後的格式,就可以直接進行loads操作,dump和load同理。pickle和json用法基本上相同,json是可以在不同語言之間交換資料的,而pickle只在python之間使用。 json只能序列化最基本的資料型別,而pickle可以序列化所有的資料型別,包括類,函式都可以序列化(不常用)
6、shelve模組(※※※)
import shelve def member_info(name, age): print("Member info:", name, age) name = ['Jack', 'Maxwell', 'Tom'] info = {'name': 'Maxwell', 'age': 18} with shelve.open('demo') as data: data['name'] = name #持久化列表 data['info'] = info #持久化字典 data['func'] = member_info
PS:shelve模組比pickle模組簡單,只有一個open函式,返回類似字典的物件,可讀可寫。key必須為字串,而值可以是python所支援的資料型別
7、xml模組(※※)
xml格式,用<>區別資料結構:
<?xml version="1.0"?> <data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2008</year> <gdppc>141100</gdppc> <neighbor name="Austria" direction="E"/> <neighbor name="Switzerland" direction="W"/> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2011</year> <gdppc>59900</gdppc> <neighbor name="Malaysia" direction="N"/> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2011</year> <gdppc>13600</gdppc> <neighbor name="Costa Rica" direction="W"/> <neighbor name="Colombia" direction="E"/> </country> </data>View Code
python中用於操作xml的模組:
import xml.etree.ElementTree as ET tree = ET.parse("xmltest.xml") root = tree.getroot() print(root.tag) #----------遍歷xml文件---------- for child in root: print(child.tag, child.attrib) for i in child: print(i.tag,i.text) #----------只遍歷year節點---------- for node in root.iter('year'): print(node.tag,node.text) #----------修改---------- for node in root.iter('year'): new_year = int(node.text) + 1 node.text = str(new_year) node.set("updated","yes") tree.write("xmltest.xml") #----------刪除node---------- for country in root.findall('country'): rank = int(country.find('rank').text) if rank > 50: root.remove(country) tree.write('output.xml')View Code
如何建立xml文件:
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) #列印生成的格式View Code
PS:json比xml用起來更簡單,但xml出現很早,以至於現在很多系統介面還是xml
8、re模組(※※※※※)
import re ret=re.findall('a..in','helloalvin') #元字元.的用法,一個.表示有一個字元 print(ret) #輸出['alvin'],re.findall是在字串中檢索所有的滿足格式的子字串並放在列表裡 ret=re.findall('^a...n','alvinhelloawwwn') #元字元^的用法,表示從字串開頭開始匹配 print(ret) #輸出['alvin'] ret=re.findall('a...n$','alvinhelloawwwn') #元字元$的用法,表示從字串結尾開始匹配 print(ret) #輸出['awwwn'] ret=re.findall('abc*','abcccc') #元字元*的用法,表示字元c重複多次,也可為0次,會自動匹配最多次,稱貪婪匹配 print(ret) #輸出['abcccc'] ret=re.findall('abc+','abccc') #元字元+的用法,表示字元c重複多次,最少有1次,會自動匹配最多次 print(ret) #['abccc'] ret=re.findall('abc?','abccc') #元字元?的用法,表示字元c重複0次或1次,會自動匹配1次 print(ret) #輸出['abc'] ret=re.findall('abc{1,4}','abccc') #元字元{}的用法,表示字元c重複指定範圍次數,會自動匹配最多次 print(ret) #輸出['abccc']
PS:上面的元字元*,+,?,{}等都是貪婪匹配,也就是按儘可能多的次數匹配,在後面加?號則可變成惰性匹配
ret=re.findall('abc*?','abcccccc') #惰性匹配字元c為最少次數0次 print(ret) #輸出['ab']
ret=re.findall('a[bc]d','acd') #元字元的字符集[]的用法,表示在字符集中選擇一個進行匹配 print(ret) #輸出['acd'] ret=re.findall('[a-z]','acd') #字符集[]中有功能的符號:-^\,a-z表示從a到z的所有字母 print(ret) #輸出['a', 'c', 'd'] ret=re.findall('[.*+]','a.cd+') #除了-^\的其他符號則變成一般字元,不具功能 print(ret) #輸出['.', '+'] ret=re.findall('[^ab]','45bdha3') #字符集[]中^表示“非”,^ab即非字元a和b print(ret) #輸出['4', '5', 'd', 'h', '3'] ret=re.findall('[\d]','45bdha3') #\d即匹配數字格式的字元 print(ret) #輸出['4', '5', '3']
import re
ret=re.findall('c\l','abc\le') #元字元\的用法,可把一般字元和特殊字元相互轉換,這裡\l有特殊意義,所以字串裡檢索不了 print(ret) #輸出[] ret=re.findall('I\b','I am LIST') #\b表示匹配一個特殊字元,比如空格 ,&,#等 #\d表示匹配任何十進位制數,相當於類 [0-9] #\D表示匹配任何非數字字元,相當於類[^0-9] #\s表示匹配任何空白字元,相當於類[ \t\n\r\f\v] #\S表示匹配任何非空白字元,相當於類[^\t\n\r\f\v] #\w表示匹配任何字母數字字元,相當於類[a-zA-Z0-9_] # \W表示匹配任何非字母數字字元,相當於類[^a-zA-Z0-9_] print(ret) #輸出[] ret=re.findall(r'I\b','I am LIST') #\b有特殊意義,所以需再次轉義\\b或r'\b' print(ret) #輸出['I'] ret=re.findall('c\\l','abc\le') print(ret) #輸出[] ret=re.findall('c\\\\l','abc\le') #python直譯器轉義和re轉義有區別,所以需傳入多個\來轉義 print(ret) #輸出['c\\l'] ret=re.findall(r'c\\l','abc\le') #直接在前面加r也可以再次轉義 print(ret) #輸出['c\\l']
m = re.findall(r'(ad)+', 'add') #元字元()的用法,將()裡的內容作為整體來匹配 m = re.findall(r'(ad)+', 'adadad') #把ab看成一個整體 print(m) #由於優先匹配()組內的內容,所以優先輸出['ad'] m1 = re.findall(r'(?:ad)+', 'adadad') #若要取消上述優先順序,則需加上?: print(m1) #輸出['ad','ad','ad'] ret=re.search('(ab)|\d','rabhdg8sd') print(ret.group()) #輸出ab,re.search函式在字串內查詢匹配到第一個符合的子字串則返回一個物件,可通過group()方法得到子符串,若沒有匹配則返回None ret=re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com') #固定格式?P<分組名稱>,id和name表示分組名稱,不參與匹配 print(ret.group()) #輸出23/com print(ret.group('id')) #輸出23,group(分組名稱)可以獲取對應的值,分組的作用是可重用多次,提高效率
re模組常用方法(上面已經講了re.findall和re.search)
import re re.match('a','abc').group() #和re.search用法一樣,但只能從字串開始處進行匹配 ret=re.split('[ab]','abcd') #先按'a'分割,左邊得到'',右邊得到'bcd',再按b分割'bcd',左邊得到'',右邊得到'cd' print(ret) #輸出['', '', 'cd'] ret=re.sub('\d','abc','alvin5yuan6',1) #引數1表示匹配規則或字元,引數2表示替換後的字串,引數3表示被匹配的字串,引數4表示匹配次數,不填則預設全部替換 print(ret) #輸出alvinabcyuan6 ret=re.subn('\d','abc','alvin5yuan6') #能得到替換後的字串和替換次數 print(ret) #輸出('alvinabcyuanabc', 2) obj=re.compile('\d{3}') #先把規則給一個物件 ret=obj.search('abc123eeee') #物件呼叫模組方法 print(ret.group()) #輸出123,優點是可重複呼叫,避免重複寫規則,提高效率 ret=re.finditer('\d','ds3sy4784a') #將查詢的內容生成迭代器 print(ret) #返回一個迭代器 print(next(ret).group()) #輸出'3',可使用group迭代輸出結果 print(next(ret).group()) #輸出'4',對於資料比較大的常用這種迭代方法,不佔記憶體
9、logging模組(※※※※※)
import logging logging.debug('debug message') #日誌級別等級CRITICAL>ERROR>WARNING>INFO>DEBUG>NOTSET logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message') #輸出WARNING:root:warning message # ERROR:root:error message # CRITICAL:root:critical message #日誌預設級別為WARNING,列印本身及後面的,格式為日誌級別:Logger名稱:使用者輸出訊息
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w') #使用basicConfig設定格式,level設定日誌級別;format指定顯示格式;datefmt指定日期時間格式;
filename指定日誌儲存的檔名;filemode指定filename的檔案開啟方式,預設值為“a” logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')#輸出cat /tmp/test.log # Sun, 13 Oct 2019 16:29:53 test_logging.py[line:9] DEBUG debug message # Sun, 13 Oct 2019 16:29:53 test_logging.py[line:10] INFO info message # Sun, 13 Oct 2019 16:29:53 test_logging.py[line:11] WARNING warning message # Sun, 13 Oct 2019 16:29:53 test_logging.py[line:12] ERROR error message # Sun, 13 Oct 2019 16:29:53 test_logging.py[line:13] CRITICAL critical message
PS:上面的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:字串形式的當前時間,預設格式 “2019-10-13 16:49:45,896”(逗號後面的是毫秒)
%(thread)d:執行緒ID,可能沒有
%(threadName)s:執行緒名,可能沒有
%(process)d:程序ID,可能沒有
%(message)s:使用者輸出的訊息
關於logger物件
import logging logger = logging.getLogger() #函式getLogger([name])返回一個logger物件,若無name則返回root logger fh = logging.FileHandler('test.log') #建立一個handler,用於寫入日誌檔案 ch = logging.StreamHandler() #再建立一個handler,用於輸出到控制檯 formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') #Formatter指定日誌顯示格式 fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) logger.addHandler(ch) #logger物件可以新增多個fh和ch物件 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') #輸出2019-10-14 19:51:23,552 - root - WARNING - logger warning message # 2019-10-14 19:51:23,552 - root - ERROR - logger error message # 2019-10-14 19:51:23,552 - root - CRITICAL - logger critical message
PS:這裡可以用logger.setLevel(logging.Debug)為logger設定日誌級別,預設的日誌級別為WARNIING,另外如果建立兩個logger物件,如果引數name相同,返回的Logger例項就是同一個,後面個的日誌級別則覆蓋前面的日誌級別,且後面的日誌會把前面的再列印一遍
10、configparser模組(※※※※)
很多軟體的文件格式是這樣:
[DEFAULT] ServerAliveInterval = 45 Compression = yes CompressionLevel = 9 ForwardX11 = yes [bitbucket.org] User = hg [topsecret.server.com] Port = 50022 ForwardX11 = noView Code
那怎麼用python生成一個這樣的文件:
import configparser config = configparser.ConfigParser() config["DEFAULT"] = {'ServerAliveInterval': '45', 'Compression': 'yes', 'CompressionLevel': '9'} #通過config加入資料,類似字典 config['bitbucket.org'] = {} config['bitbucket.org']['User'] = 'hg' config['topsecret.server.com'] = {} topsecret = config['topsecret.server.com'] topsecret['Host Port'] = '50022' topsecret['ForwardX11'] = 'no' config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as configfile: config.write(configfile)
操作:
import configparser config = configparser.ConfigParser() config.read('example.ini') #需要先進行read再進行查詢操作 print(config.sections()) #輸出除了第一個的key,為['bitbucket.org', 'topsecret.server.com'] print('bytebong.com' in config) #輸出False print(config['bitbucket.org']['User']) #輸出hg for key in config['topsecret.server.com']: print(key) #輸出Port #ForwardX11 print(config.options('bitbucket.org')) #輸出['user'],即key print(config.items('bitbucket.org')) #輸出[('user', 'hg')],即整個items print(config.get('DEFAULT','compression')) #輸出yes #---------------------------------------------------------------查詢操作 config.add_section('yuan') #---------------------------------------------------------------增加操作 config.remove_section('topsecret.server.com') config.remove_option('bitbucket.org','user') #---------------------------------------------------------------刪除操作 config.set('bitbucket.org','k1','11111') #---------------------------------------------------------------修改操作 config.write(open('i.cfg', "w")) #可以直接通過函式開啟,不用關閉View Code
11、hashlib模組(※※)
import hashlib m=hashlib.md5() #也可以用m=hashlib.sha256(),此模組主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5演算法 m.update('hello'.encode('utf8')) #要進行雜湊的的字串“hello” print(m.hexdigest()) #輸出5d41402abc4b2a76b9719d911017c592 m.update('alvin'.encode('utf8')) print(m.hexdigest()) #輸出92a7e713c30abbb0319fa07da2a5c4af m2=hashlib.md5() #另外定義一個變數 m2.update('helloalvin'.encode('utf8')) #把前兩個字串連起來處理 print(m2.hexdigest()) #輸出92a7e713c30abbb0319fa07da2a5c4af,即上面的m是先雜湊hello,再加上alvin雜湊
那麼現在有一個很大的資料庫,統計了很多常用的字串,於是可能會被反解,稱為撞庫。為了避免這種情況可以用以下這種方法:
import hashlib m = hashlib.sha256('898oaFs09f'.encode('utf8')) #在處理之前加一段雜湊的隨機字串 m.update('alvin'.encode('utf8')) print(m.hexdigest())#輸出04d0625659c27032274faf030cd842676be3b8912bb255f9d3445d86c1e5de80
當然python還有一個hmac模組,它內部對我們建立key和內容,然後再進行處理後加密:
import hmac h = hmac.new('alvin'.encode('utf8')) h.update('hello'.encode('utf8')) print (h.hexdigest()) #輸出320df9832eab4c038b6c1d7ed73a5940
&n