目錄:1.模塊 2.包 3.絕對導入與相對導入 4.time模塊 5.random模塊 6.os模塊 7.sys模塊 8.json&pickle模塊 9.shelve模塊 10.xml模塊 11.configparser模塊 12. hashlib模塊 13.subprocess模塊 14.logging模塊 15.re模塊 16.軟件開發規範python
模塊:git
分類:內置模塊,第三方模塊,自定義模塊正則表達式
調用方式:算法
import moduleshell
from module import xxx數據庫
from module.xx.xx import xx as renamejson
from module.xx.xx import *windows
模塊一旦被調用,至關於執行了其中的代碼緩存
程序在哪執行,sys.path中就默認有當前目錄的路徑 安全
跨模塊導入時要添加環境變量,把父級路徑添加到sys.path中
import sys,os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path打印一個列表,第一個元素是 ’ ’ 就是當前目錄的路徑
__file__就是當前程序的路徑,pycharm裏是絕對路徑,python2中是相對路徑
因此最好使用os.path.abspath(__file__)拿到絕對路徑
if __name__==’__main__’ 該文件就當作腳本去執行
__all__=[] 列表裏面寫字符串形式的內容,這樣from … import * 這樣操做的時候*再也不表明全部的內容了,只表明[]內的全部內容
包:
一個文件夾管理多個模塊文件,這個文件夾就被稱爲包
包就是文件夾,該文件夾下有__init__.py文件
導入包的時候,會先執行包下面的__init__文件
凡是在導入的時候帶 . 的, . 的左邊都必須是一個包
from … import … 這種格式的時候,import後面的不能有.
from … import *這樣導入包的時候,*只會導入包下面__init__文件中的內容,咱們能夠在這個文件中自定義__all__=[]
絕對導入與相對導入
在涉及相對導入時,package所對應的文件夾必須正確的被python解釋器視爲package,而不是普通文件夾
文件夾被python解釋器視做package須要知足的條件:
1.文件夾中必須有__init__.py文件,該文件能夠爲空,但必須存在該文件
2.不能做爲頂層模塊來執行該文件夾中的py文件(即不能做爲主函數的入口),
即用..的時候包不能跟入口程序在同一層
.表明__init__當前的目錄,就是跟執行的程序入口在同一級目錄,..表明__init__上一級目錄
相對導入用的很少,不建議用
time模塊:
python中一般有以下方式表示時間
1.時間戳 time.time() 是從1970年1月1日00:00:00開始計算到如今的秒數
2格式化的時間字符串,time.strftime(「%Y-%m-%d %X」),獲得2018-04-09 17:06:32 Y改爲y就顯示18
3元組,即結構化時間 time.localtime() 拿到的是時間每一個部分組成的一個元組,能夠每一部分都取出來而後從新組合
結構化時間到字符串時間用strftime,字符串時間到結構化時間strptime
結構化時間到時間戳用mktime,時間戳到結構化時間用localtime或gmtime
字符串時間與時間戳之間不能直接轉化
time.asctime()獲取當前時間,格式是周 月 日 時 分 秒 年 time.ctime()
time.mktime(time.strptime('2021-02-01','%Y-%m-%d')) 實現字符串時間到時間戳的轉化
即先用strptime將字符串時間轉成結構化時間,再用mktime將結構化時間轉成時間戳
time.strptime(字符串時間)--->結構化時間 time.mktime(結構化時間)--->時間戳
time.strftime('%Y-%m-%d',time.localtime(time.time())) 實現時間戳到字符串時間的轉化
即先用localtime將時間戳轉成結構化時間,再用strftime將結構化時間轉成字符串時間
time.localtime(時間戳) or time.gtime(時間戳)--->結構化時間 time.strftime(結構化時間)--->字符串時間
datetime模塊:
datetime.date.fromtimestamp() 把一個時間戳轉成datetime日期類型
datetime.datetime.now()返回當前時間,格式是年月日時分秒
時間運算:
datetime.datetime.now() - datetime.timedelta(days = 1)
減一天,能夠寫days,hours,minutes,seconds,可加可減
時間替換:
d = datetime.datetime.now()
d.replace(year = 1990,month = 10)能夠替換出來一個本身指定的時間
random模塊:
random.random() 獲得的是0~1之間的小數
random.randint(1,s) 大於等於1且小於等於s之間的整數
random.randrange(1,s) 大於等於1且小於s之間的整數,能夠再加一個參數(1,8,2)2是步長的意思,從1開始,結果都是奇數
random.choice([1,’23’,(4,5)]) 1或’23’或(45),隨機返回一個,裏面能夠放列表、字符串,返回一個
random.sample([1,’23’,(4,5)],2) 由於在最後一個位置設定了參數2,因此結果是從裏面選兩個組成列表,返回多個組成的列表
random.uniform(1,s) 大於1小於s的小數
random.shuffle(item) 打亂次序
random實例:
chr()括號裏面加數字能夠獲得ASCII碼中對應的字母
作一個五位數的驗證碼
一:
def validate():
s=''
for i in range(5): 控制驗證碼的字母或數字個數
rNum=random.randint(0,9) randint獲得一個0-9包括9的隨機整數
alpha=chr(random.randint(65,90)) 先獲得65-90包括90的隨機整數,而後用chr獲得對應的ASCII碼中的字母
res=random.choice([rNum,alpha]) choice從整數或字母中隨機選出一個賦值給res括號裏面必須寫列表的形式
s+=str(res)
return s
print(validate())
二:
num = string.digits 拿到0-9
alpha = string.ascii_lowercase 拿到小寫的a-z
s = alpha + num 把a-z跟0-9組成一個字符串
‘’.join(random.sample(s,5))先用random.sample拿到一個五個元素組成的列表,再用join方法把列表轉成字符串
string模塊:
string.digits 返回字符串格式的'0123456789'
string.ascii_letters 返回全部的小寫字母和大寫字母組成的字符串
string.ascii_lowercase 返回全部小寫字母組成的字符串
os模塊:
os模塊是與操做系統交互的一個接口
os.getcwd()獲取當前工做目錄,即當前python腳本所在的目錄路徑
os.chdir(「dirname」)改變當前腳本工做目錄,至關於shell下的cd,沒有返回值
os.curdir返回當前目錄:(’.’)
os.pardir獲取當前目錄的父目錄字符串名:(‘..’)
os.remove() 刪除一個文件
os.removedirs(‘dirname1’)若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,以此類推
os.mkdir(‘dirname’)生成單級目錄,至關於shell中mkdir dirname
os.makedirs(‘dirname1/dirname2’)可生成多層遞歸目錄
os.rmdir(‘dirname’)刪除單級目錄,若目錄不爲空則沒法刪除,報錯 ,至關於shell中remdir dirname
os.listdir(‘dirname’)列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.rename(‘oldname’,’newname’)重命名文件/目錄
os.stat(‘path/filename’)獲取文件/目錄信息
os.sep 輸出操做系統特定的路徑分隔符,win下爲」\\」,Linux下爲」/」
os.linesep輸出當前平臺使用的行終止符,win下爲」\r\n」,Linux下爲」\n」
os.pathsep輸出用於分割文件路徑的字符串,win下爲;,Linux下爲:
os.name輸出字符串指示當前使用平臺win->’nt’ Linux->’posix’
os.system(「bath command」)運行shell命令,直接顯示,這個方法是拿不到結果的,就是結果不能賦值給變量保存或傳輸
os.environ獲取系統環境變量
os.path.abspath(path)返回path規範化的絕對路徑
os.path.split(path)將path分割成目錄和文件名二元組返回,(‘目錄名’,‘文件名’)
os.path.dirname(path)返回path的目錄,其實就是os.path.split(path)的第一個元素
os.path.basename(pash)返回path最後的文件名,若是path以/或\結尾,那麼返回空值,即os.path.split(path)的第二個元素
os.path.exists(path)若是path存在,返回True,不存在返回False
os.path.normpath(path) 標準化路徑名,合併多餘的分隔符和上層引用,在windows平臺上還會把斜線轉換成反斜線
os.path.isabs(path)若是path是絕對路徑,返回True
os.path.isfile(path)若是path是一個存在的文件,返回True
os.path.isdir(path)若是path是一個存在的目錄,返回True,用..的時候會自動往前走三級目錄
os.path.join(path1[,path2[,…]])將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)返回path所指向的文件或者目錄的最後訪問時間
os.path.getmtime(path)返回path所指向的文件或者目錄的最後修改時間
os.path.getsize(path)返回path的大小
os.walk的用法:
def file_name(file_dir):
for root, dirs, files in os.walk(file_dir):
print(root) #當前目錄路徑
print(dirs) #當前路徑下全部子目錄
print(files) #當前路徑下全部非目錄子文件
sys模塊:
sys.argv 命令行參數List,第一個元素是程序自己路徑
sys.exit(n)退出程序,正常退出時exit()
sys.version獲取python解釋程序的版本信息
sys.maxint獲取最大的int值
sys.path返回模塊的搜索路徑,是一個列表,初始化時使用pythonpath環境變量的值
sys.plaform返回操做系統平臺名稱
sys.modules 返回內存裏面都導入了哪些模塊
shutil模塊:
shutil.copyfileobj() 將文件內容拷貝到另外一個文件中,該操做須要打開文件
shutil.copyfileobj(open('old.xml','r'),open('new.xml','w'))
shutil.copyfile() 拷貝文件,目標文件無需存在,該操做無需打開文件,就直接寫文件名就能夠
shutil.copymode() 拷貝權限,目標文件必須存在
shutil.copystat() 拷貝狀態的信息,目標文件必須存在
shutil.copy() 拷貝文件和權限
shutil.copy2() 拷貝文件和狀態信息
shutil.copytree() 遞歸着去拷貝文件夾,要拷貝生成的新目錄不能存在,否則會報錯
shutil.copytree('package','pack2',ignore=shutil.ignore_patterns("__init__.py"))
第一個元素是要拷貝的文件夾,第二個元素師要生成的新目錄
第三個元素是symlinks=False,通常默認是這樣的,就不用寫了
第四個元素是排除的意思,在拷貝的時候,哪些內容不拷貝,寫到這裏面
shutil.rmtree() 遞歸着去刪除文件
shutil.move() 遞歸着去移動文件,相似於mv命令,至關於重命名
shutil.make_archive() 建立壓縮包並返回文件路徑
括號裏面能夠放的參數:
base_name: 壓縮包的文件名,也能夠是壓縮包的路徑,只是文件名時,則保存到當前目錄,不然保存到指定路徑
format: 壓縮包種類,zip,tar,bztar,gztar
root_dir: 要壓縮的文件夾路徑(默認是當前目錄)
owner: 用戶,默認是當前用戶
group: 組,默認是當前組
logger: 用於記錄日誌,一般是logging.Logger對象
shutil.make_archive('data_bak','gztar',root_dir='/data')
將data下的文件打包到data_bak目錄下
json&pickle模塊:
什麼叫序列化?
序列化是指把內存裏的數據類型轉變成字符串,以使其能存儲到硬盤或網絡傳輸到遠程,由於硬盤或網絡傳輸只接受bytes
把字符轉成內存數據叫作反序列化
序列化自己就是一次的,dump一次,load一次,若是dump兩次,那load的時候就會報錯,dump屢次不會報錯
json,用於字符串和python數據類型之間進行轉換,字典格式的json字符串,第一個key必須用""雙引號,文件後綴是.json
序列化完了是字符串的格式,就能夠用於存儲和網絡傳輸了
pickle,用於python特有的類型和python的數據類型之間進行轉換,文件後綴是.pkl,序列化完了就直接是bytes的格式
因此用pickle的時候,關於文件的操做要注意用‘rb’/'wb'
二者用法徹底同樣
二者都有四個功能,dumps、dump、loads、load
pickle.dumps()將數據經過特殊的形式轉換成只有python語言認識的bytes格式,括號中放數據
pickle.dump() 將數據經過特殊的形式轉換成只有python語言認識的bytes格式,並寫入文件,括號中放兩個參數,一個是數據,一個是文件句柄
json.dumps()將數據經過特殊的形式轉換成全部程序語言都認識的字符串
json.dump() 將數據經過特殊的形式轉換成全部程序語言都認識的字符串,並寫入文件,括號中放兩個參數,一個是數據,一個是文件句柄
文件句柄須要是寫模式的
loads是反序列化的過程,與dumps對應
load與dump對應
d1 = json.dumps(data) 將data序列化成字符串格式並賦值給d1
d2 = json.loads(d1) 將序列化獲得的d1反序列化成原來的數據類型並賦值給d2
f1 = open('test.json','w') 打開要把數據寫入的文件,讀模式
json.dump(data,f1) 將data序列化成字符串格式,並寫入到文件中
f2 = open('test.json','r') 打開要讀取數據的文件,讀模式
d3 = json.load(f2) 將文件f2中字符串格式的內容反序列化成原來的數據類型並賦值給d3
load括號裏放文件句柄,loads括號裏放bytes格式的對象,也能夠放f.read()
json與pickle的比較:
json:跨語言、體積小,可是隻支持int、str、list、tuple、dict
pickle:專爲python設計,支持python全部數據類型,但只能在python中使用,存儲數據佔空間大
json.dumps()與json.loads() 只是把數據類型轉成字符串並保存到內存裏,其意義在於:
把內存數據經過網絡共享給遠程
定義了不一樣語言之間的交互規則:
1.純文本,壞處是不能共享複雜的數據類型
2.xml,壞處是佔空間大
3.json,簡單,可讀性好,跨語言
shelve模塊:
爲了解決json和pickle只能dump一次的問題
是對pickle進行了封裝,pickle是python獨有的,因此shelve只能在python中使用
import shelve
f = shelve.open('shelve_test') #打開一個文件
names = ['alex','rain','test']
info = {'name':'alex','age':22}
f['names'] = names #持久化列表
f['info'] = info #持久化字典
f.close()
xml模塊:
是實現不一樣語言或程序之間進行數據交換的協議
在各個語言中都支持
configparser模塊:
用於生成和修改常見配置文檔
hashlib模塊:
Hash:一種將任意長度的消息壓縮到某一個固定長度的消息摘要的函數
用於信息安全領域中加密算法,hash就是找到一種數據內容與數據存放地址之間的映射關係
MD5:輸入任意長度的消息,通過處理,輸出爲128位的消息,不一樣的輸入獲得不一樣的結果
用於防止被篡改,防止直接看到明文,防止抵賴
特色:
壓縮性,任意長度的數據算出的MD5值都是固定長度的128位
容易計算,從原數據計算出MD5值很容易
抗修改性,對於原數據進行任何改動,修改一個字節生成的MD5值區別也會很大
強抗碰撞,已知原數據與MD5值,想找到一個具備相同MD5值的數據也很是困難
MD5不可逆
SHA-1:安全哈希算法,對於長度小於2^64位的消息,SHA1會產生一個160位的消息摘要
最流行的加密算法是SHA-256
SHA-1比MD5的摘要多32比特,抵禦強行攻擊更強,可是緩存也要更大,運行更慢
實例:
import hashlib
m=hashlib.md5() #括號裏能夠加參數,就是俗稱的「加鹽」,提升安全性
m.update("3714".encode('utf-8'))
print(m.hexdigest()) digest是二進制格式,hexdigest是十六進制格式
m.update(b"3714") #37143714 由於上面已經update了一個3714,因此這裏是37143714
print(m.hexdigest())
n=hashlib.sha1()
n.update(b"3714")
print(n.hexdigest())
subprocess模塊:
統一的模塊來實現對 系統命令或腳本 的調用
三種執行命令的方法:
1.subprocess.run() 官方推薦
2.subprocess.call()
3.subprocess.Popen()
run()標準寫法 錯誤 直接.stderr查看 標準輸出 直接.stdout查看
subprocess.run(['df','-h'],stderr=subprocess.PIPE,stdout=subprocess.PIPE,check=True)
check = True ,默認是False的,這樣的話若是加的命令沒有也不會報錯,寫成True命令不存在就會報錯
涉及到管道|的命令以下寫,由於subprocess.PIPE也是一個相似於管道的東西
subprocess.run('df -h|grep disk1',shell=True)
shell=True的意思是這條命令直接交給系統去執行,不須要python負責解析
call() 方法 用的很少
subprocess.call(['ls','-l']) 執行命令,返回命令執行狀態
subprocess.check_call(['ls','-l']) 執行命令,若是命令結果爲0,則正常返回,不然拋異常
subprocess.gestatusoutput('ls /bin/ls') 接受字符串格式命令,返回元祖形式,第一個元素是命令執行狀態
第二個元素是執行結果
subprocess.getoutput('ls /bin/ls') 接收字符串格式命令,並返回結果
Popen() 方法 這個最重要,上面的call跟run底層都是封裝的Popen方法
args:shell命令,能夠是字符串或者序列類型
stdin、stdout、stderr:程序的標準輸入、輸出和錯誤句柄
shell:跟run同樣shell = True 就是把命令交給操做系統去執行
a = subprocess.Popen('Python3 guess_age.py',
stdout = subprocess.PIPE,
stdin = subprocess.PIPE,
stderr = subprocess.PIPE,
shell = True)
a.communicate(b'22')
Popen方法在發起命令後馬上返回,而不等待命令執行結果
logging模塊:
五個級別,由高到低:
logging.critical()>logging.error()>logging.warning()>logging.info()>logging.debug()
默認狀況下python的logging模塊將日誌打印到了標準輸出中,
且只顯示了大於等於warning級別的日誌,這說明默認的日誌級別設置爲warning
logging.warning('------warning') 運行就直接打印了,默認輸出到屏幕
這個只能輸出到文件
logging.basicConfig()函數中可經過具體參數來更改logging模塊默認行爲,可用參數有:
filename:用指定的文件名建立FiledHandler,這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值爲「a」還可指定爲「w」。
datefmt:指定日期時間格式。
level:設置rootlogger(後邊會講解具體概念)的日誌級別
format:指定handler使用的日誌顯示格式。
%(name)s Logger的名字
%(levelno)s 數字形式的日誌級別 info是10,debug是20,warning是30,error是40,critical是50
%(levelname)s 文本形式的日誌級別
%(filename)s 調用日誌輸出函數的模塊的文件名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(asctime)s 字符串形式的當前時間,默認格式是"2018-04-10 11:10:45.896"
%(message)s 用戶輸出的消息
日誌同時輸出到屏幕與文件
logger 提供了應用程序能夠直接使用的接口
handler 將logger建立的日誌記錄發送到合適的目的輸出
filter 提供了細度設備來決定輸出哪條日誌記錄,能夠理解爲按照某種條件進行篩選過濾
formatter 決定日誌記錄的最終輸出格式
logger:一般對應了程序的模塊名
logger = logging.getLogger()
還能夠綁定handler與filters
logger.setLevel() 指定最低日誌級別,這裏是設置整個logger的最低日誌級別,若是handler設置的高於這個,會按照那個輸出
logger.addFilter() logger.removeFilter() 添加或刪除指定的filter
logger.addHandler() logger.removeHandler() 添加或刪除指定的handler
logger.debug() logger.info() logger.warning() logger.error() logger.critical()
設置日誌級別
handler:負責發送相關的信息到指定目的地
handler.setLevel() 指定被處理的信息級別,給handler設置級別,可讓輸出到文件的跟輸出到屏幕的不同
此處設置的日誌級別不能低於logger.setlevel() 設置的日誌級別,否則不會生效
handler.setFormatter() 給這個handler選擇一個格式
handler.addFilter() handler.removeFilter() 添加或刪除一個filter對象
每一個logger能夠附加多個handler
經常使用handler:
logging.StreamHandler() 輸出到屏幕
使用這個handler能夠相相似與sys.stdout或sys.stderr的任何文件對象輸出信息
logging.FileHandler() 輸出到文件
與上者相似,用於向一個文件輸出日誌信息,但這個會幫你打開文件
logging.handlers.RotatingFileHandler()
與FileHandler相似,可是能夠管理文件大小,當文件達到必定大小的時候,自動將當前文件更名
並生成一個新的同名日誌文件繼續輸出
logging.handlers.TimedRotatingFileHandler()
與上面相似,但不是判斷文件大小,而是間隔必定時間就自動建立新的
formatter:
日誌的formatter是獨立組件,能夠跟handler組合
fh = logging.FileHandler('access.log‘) 拿到一個handler方法
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter) 調用handler下面的功能,把formatter綁定到fh
實例:
import logging
def logger():
logger=logging.getLogger()
fh=logging.FileHandler('logger2')
sh=logging.StreamHandler()
formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
sh.setFormatter(formatter)
logger.addHandler(fh)
logger.addHandler(sh)
return logger
logger=logger()
logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.error('error')
logger.critical('critical')
re模塊
正則表達式就是字符串的匹配規則,本質上正則要實現的是模糊匹配
re.findall() 把全部符合正則條件的內容放到一個列表中返回,有返回值
re.match() 從頭開始匹配,只匹配字符串中的第一個字符,返回對象
re.search() 匹配包含,只匹配字符串中的一個,返回對象,匹配到了之後用.group()拿到要匹配的內容,分組匹配用.groups()拿到
re.split() 以匹配到的字符當作列表分隔符,能夠在最後加參數限定分割次數,有點跟findall相反的意思
findall是拿到符合條件的放到一個列表中,只要符合條件的,而split是用符合條件的做爲分隔符,把其餘內容放到列表中
re.sub() 匹配字符並替換
re.subn() 會把替換的次數一併返回,以元組的形式
re.fullmatch() 所有匹配
以上方法,括號內兩個參數,第一個是正則規則,規則用‘’引發來,第二個是數據
貪婪匹配:在知足匹配時,匹配儘量長的字符串,默認狀況下采用貪婪匹配
非貪婪匹配:在知足匹配時,匹配儘量短的字符串,使用?開頭來表示非貪婪匹配
元字符是正則最核心的內容
. 通配符,能夠匹配除換行符\n之外的任意一個符號
^ 匹配字符開頭
$ 匹配字符結尾
* 匹配*前的字符0次或屢次
+ 匹配+前一個字符一次或屢次
? 匹配?前一個字符一次或零次
{m} 匹配前一個字符m次
{n,m} 匹配前一個字符n到m次
| 或
[] 字符集 若是是a[bd]c 匹配到的是abc和adc
若是字符集裏面放* + ?等這種元字符,那它們就失去了本來的功能,變成一個普通字符
字符集裏面能夠放的符號:- 表示範圍
^ 放在字符集裏面表示取反,再也不是之前的開始匹配
\ 仍是之前的功能,是一個轉義符
() 分組匹配,按照匹配規則,匹配獲得的結果優先是括號裏面的內容
能夠在括號開頭加?:取消優先級
(?P<name>)命名分組
\ 轉義符,後面跟不一樣的內容有不一樣的意思
後面跟的是元字符則去除其特殊功能,變成普通字符 如\. \*
後面跟特定的普通字符實現特殊功能,以下
\d 匹配數字0-9 等於[0-9] 常常用
\D 匹配任何非數字字符
\s 匹配任何空白字符
\S 匹配任何非空白字符
\w 匹配任何字母數字字符 [a-zA-Z0-9] 常常用
\W 匹配任何非字母數字字符 非[a-zA-Z0-9]
\b 匹配一個特殊字符邊界,好比空格 & # 等
\A 只從字符開頭匹配 等同於^
\Z 匹配字符結尾,等同於$
軟件開發規範
bin 可執行文件
conf 配置文件
core 核心代碼 也能夠就叫項目名稱,項目名稱通常是用小寫的
db 數據庫文件
docs 說明文檔
lib 庫文件,放本身製做的自定義模塊或包
log 日誌文件
README 文本文件
1.軟件定位,軟件的基本功能
2.運行代碼的方法:安裝環境、啓動命令等
3.簡要的使用說明
4.代碼目錄結構說明,更詳細點能夠說明軟件的基本原理
5.常見問題說明