1. 程式人生 > >python模組常用用法

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 = no
View 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