常見(jiàn)模塊

一.time與datetime模塊

1.time模塊的三種形式

import time

1.時(shí)間戳:從1970年到現(xiàn)在經(jīng)過(guò)的秒數(shù)

作用:用于時(shí)間間隔的計(jì)算

print(time.time()) #1585531244.1986158

2.按照某種格式顯示的時(shí)間

作用:用于展示時(shí)間

print(time.strftime('%Y-%m-%d %H:%M:%S %p'))
print(time.strftime('%Y-%m-%d %X'))
# 2020-03-30 09:20:44 AM
# 2020-03-30 09:20:44

3.結(jié)構(gòu)化時(shí)間

作用:用于獲取時(shí)間的某一部分

#localtime([secs])
# 將一個(gè)時(shí)間戳轉(zhuǎn)換為當(dāng)前時(shí)區(qū)的struct_time。secs參數(shù)未提供颓芭,則以當(dāng)前時(shí)間為準(zhǔn)芜抒。
res=time.localtime() 
print(res) # time.struct_time(tm_year=2020, tm_mon=3, tm_mday=30, tm_hour=9, tm_min=20, tm_sec=44, tm_wday=0, tm_yday=90, tm_isdst=0)
print(res.tm_year) # 2020
print(res.tm_yday) #90

2.datetime的模塊

import datetime
print(datetime.datetime.now())
print(datetime.datetime.now()+datetime.timedelta(days=3))
print(datetime.datetime.now()+datetime.timedelta(weeks=3))
# 2020-03-30 15:11:01.141467
# 2020-04-02 15:11:01.141467
# 2020-04-20 15:11:01.141467

3.時(shí)間模塊需要掌握的操作

1.時(shí)間格式的轉(zhuǎn)換

結(jié)構(gòu)化的時(shí)間(struct_time)-->時(shí)間戳

import time
s_time=time.localtime()
# mktime(t) : 將一個(gè)struct_time轉(zhuǎn)化為時(shí)間戳
print(time.mktime(s_time)) 

時(shí)間戳-->結(jié)構(gòu)化的時(shí)間(struct_time)

import time
t_time=time.localtime()
print(time.localtime(t_time))

補(bǔ)充:世界標(biāo)準(zhǔn)時(shí)間與本地時(shí)間

print(time.localtime()) # tm_hour=15
print(time.gmtime())    #  tm_hour=7 # 世界標(biāo)準(zhǔn)時(shí)間

結(jié)構(gòu)化的時(shí)間(struct_time)-->格式化的字符串形式的時(shí)間

s_time=time.localtime()
# strftime(format[, t]) : 把一個(gè)代表時(shí)間的元組或者struct_time(如由time.localtime()和
time.gmtime()返回)轉(zhuǎn)化為格式化的時(shí)間字符串。
print(time.strftime('%Y-%m-%d %H:%M:%S',s_time))
#2020-03-30 15:28:27

真正需要掌握的只有一條:format string<------>timestamp

'1988-03-03 11:11:11'+7

format string--->struct_time--->timestamp

# time.strptime(string[, format])
# 把一個(gè)格式化時(shí)間字符串轉(zhuǎn)化為struct_time败潦。實(shí)際上它和strftime()是逆操作嗡贺。
struct_time=time.strptime('1988-03-03 11:11:11','%Y-%m-%d %H:%M:%S')
print(struct_time) 
timestamp=time.mktime(struct_time)+7*86400
print(timestamp)

format string<---struct_time<---timestamp

res=time.strftime('%Y-%m-%d %X',time.localtime(timestamp))
print(res)
#sleep(secs)
#線程推遲指定的時(shí)間運(yùn)行讶隐,單位為秒。
time.sleep(3)

了解

# asctime([t]) : 把一個(gè)表示時(shí)間的元組或者struct_time表示為這種形式:'Mon Mar 30 15:50:38 2020'雀鹃。
# 如果沒(méi)有參數(shù)幻工,將會(huì)將time.localtime()作為參數(shù)傳入。
print(time.asctime())#Mon Mar 30 15:50:38 2020

# ctime([secs]) : 把一個(gè)時(shí)間戳(按秒計(jì)算的浮點(diǎn)數(shù))轉(zhuǎn)化為time.asctime()的形式黎茎。如果參數(shù)未給或者為None的時(shí)候囊颅,將會(huì)默認(rèn)time.time()為參數(shù)。它的作用相當(dāng)于time.asctime(time.localtime(secs))傅瞻。
print(time.ctime())  # Mon Mar 30 15:52:16 2020
print(time.ctime(time.time()))  #Mon Mar 30 15:52:16 2020
import datetime
print(datetime.datetime.now()) # 2020-03-30 15:54:06.155174
print(datetime.datetime.utcnow())  # 2020-03-30 07:54:06.155174
print(datetime.datetime.fromtimestamp(333333))  # 1970-01-05 04:35:33

二.random模塊

import random
print(random.random()) #大于0且小于1之間的小數(shù)
print(random.randint(1,3)) #[1,3] #大于等于1且小于等于3之間的整數(shù)
print(random.randrange(1,3)) # # [1,3)  #大于等于1且小于3之間的整數(shù)
print(random.sample([111,'aaa','ccc','ddd'],2)) # 列表元素任意2個(gè)組合
print(random.choice([1,23,[4,5]])) # 1或者23或者[4,5]
print(random.uniform(1,3)) # 大于1小于3的小數(shù)
import random
item=[1,3,5,7,9]
random.shuffle(item) # 打亂item的順序,相當(dāng)于"洗牌"
print(item)
#隨機(jī)驗(yàn)證碼
import random
def make_code(size=6):
    res=''
    for i in range(size):
        s1=chr(random.randint(65,90))
        s2=str(random.randint(0,9))
        res+=random.choice([s1,s2])
    return res
print(make_code())

三.os模塊

os模塊是與操作系統(tǒng)交互的一個(gè)接口

os.getcwd() 獲取當(dāng)前工作目錄踢代,即當(dāng)前python腳本工作的目錄路徑
os.chdir("dirname")  改變當(dāng)前腳本工作目錄;相當(dāng)于shell下cd
os.curdir  返回當(dāng)前目錄: ('.')
os.pardir  獲取當(dāng)前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄為空嗅骄,則刪除胳挎,并遞歸到上一級(jí)目錄,如若也為空溺森,則刪除慕爬,依此類推
os.mkdir('dirname')    生成單級(jí)目錄;相當(dāng)于shell中mkdir dirname
os.rmdir('dirname')    刪除單級(jí)空目錄屏积,若目錄不為空則無(wú)法刪除医窿,報(bào)錯(cuò);相當(dāng)于shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的所有文件和子目錄炊林,包括隱藏文件姥卢,并以列表方式打印
os.remove()  刪除一個(gè)文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息
os.sep    輸出操作系統(tǒng)特定的路徑分隔符,win下為"\\",Linux下為"/"
os.linesep    輸出當(dāng)前平臺(tái)使用的行終止符渣聚,win下為"\t\n",Linux下為"\n"
os.pathsep    輸出用于分割文件路徑的字符串 win下為;,Linux下為:
os.name    輸出字符串指示當(dāng)前使用平臺(tái)独榴。win->'nt'; Linux->'posix'
os.system("bash command")  運(yùn)行shell命令,直接顯示
os.environ  獲取系統(tǒng)環(huán)境變量
os.path.abspath(path)  返回path規(guī)范化的絕對(duì)路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄饵逐。其實(shí)就是os.path.split(path)的第一個(gè)元素
os.path.basename(path)  返回path最后的文件名括眠。如何path以/或\結(jié)尾,那么就會(huì)返回空值倍权。即os.path.split(path)的第二個(gè)元素
os.path.exists(path)  如果path存在,返回True;如果path不存在薄声,返回False
os.path.isabs(path)  如果path是絕對(duì)路徑当船,返回True
os.path.isfile(path)  如果path是一個(gè)存在的文件,返回True默辨。否則返回False
os.path.isdir(path)  如果path是一個(gè)存在的目錄德频,則返回True。否則返回False
os.path.join(path1[, path2[, ...]])  將多個(gè)路徑組合后返回缩幸,第一個(gè)絕對(duì)路徑之前的參數(shù)將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最后存取時(shí)間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最后修改時(shí)間
os.path.getsize(path) 返回path的大小
import os
# 獲取某一個(gè)文件夾下所有的子文件以及子文件夾的名字
res=os.listdir('.')
print(res)

size=os.path.getsize(r'/Users/linhaifeng/PycharmProjects/s14/day22/01 時(shí)間模塊.py')
print(size)

os.remove()  刪除一個(gè)文件
os.rename("oldname","newname")  重命名文件/目錄
# 應(yīng)用程序----》"ls /"
os.system("ls /")

# 規(guī)定:key與value必須都為字符串
os.environ['aaaaaaaaaa']='111'
print(os.environ)

print(os.path.dirname(r'/a/b/c/d.txt')) # /a/b/c
print(os.path.basename(r'/a/b/c/d.txt')) # d.txt

print(os.path.isfile(r'筆記.txt'))
print(os.path.isfile(r'aaa'))
print(os.path.isdir(r'aaa'))
print(os.path.join('a','/','b','c','d')) #/b\c\d

os路徑處理 推薦使用

BASE_DIR=os.path.dirname(os.path.dirname(__file__))
print(BASE_DIR)

在python3.5之后壹置,推出了一個(gè)新的模塊pathlib

from pathlib import Path
res = Path(__file__).parent.parent
print(res)
res=Path('/a/b/c') / 'd/e.txt'
print(res)
print(res.resolve())

BASE_DIR=os.path.normpath(os.path.join(
    __file__,
    '..',
    '..'
))
print(BASE_DIR)

四.sys模塊

sys.argv           命令行參數(shù)List,第一個(gè)元素是程序本身路徑
sys.exit(n)        退出程序表谊,正常退出時(shí)exit(0)
sys.version        獲取Python解釋程序的版本信息
sys.maxint         最大的Int值
sys.path           返回模塊的搜索路徑钞护,初始化時(shí)使用PYTHONPATH環(huán)境變量的值
sys.platform       返回操作系統(tǒng)平臺(tái)名稱
# python3.8 run.py 1 2 3
# sys.argv獲取的是解釋器后參數(shù)值
print(sys.argv)

src_file=input('源文件路徑: ').strip()
dst_file=input('目標(biāo)文件路徑: ').strip()
src_file=sys.argv[1]
dst_file=sys.argv[2]
# 判斷
with open(r'%s' %src_file,mode='rb') as read_f,\
    open(r'%s' %dst_file,mode='wb') as write_f:
    for line in read_f:                       write_f.write(line)
    
# python3.8 run.py src_file dst_file

進(jìn)度條

#進(jìn)度條的效果
[#             ]
[##            ]
[###           ]
[####          ]

#指定寬度
print('[%-15s]' %'#')
print('[%-15s]' %'##')
print('[%-15s]' %'###')
print('[%-15s]' %'####')

#打印%
print('%s%%' %(100)) #第二個(gè)%號(hào)代表取消第一個(gè)%的特殊意義

#可傳參來(lái)控制寬度
print('[%%-%ds]' %50) #[%-50s]
print(('[%%-%ds]' %50) %'#')
print(('[%%-%ds]' %50) %'##')
print(('[%%-%ds]' %50) %'###')

import time
res=''
for i in range(50):
    res+='#'
    time.sleep(0.5)
    print('\r[%-50s]' % res,end='')
import time
def progress(percent):
    if percent > 1:
        percent = 1
    res = int(50 * percent) * '#'
    print('\r[%-50s] %d%%' % (res, int(100 * percent)), end='')
recv_size=0
total_size=1025011

while recv_size < total_size:
    time.sleep(0.01) # 下載了1024個(gè)字節(jié)的數(shù)據(jù)

    recv_size+=1024 # recv_size=2048

    # 打印進(jìn)度條
    # print(recv_size)
    percent = recv_size / total_size  # 1024 / 333333
    progress(percent)

五.shutil模塊

高級(jí)的 文件、文件夾爆办、壓縮包 處理模塊

shutil.copyfileobj(fsrc, fdst[, length])
將文件內(nèi)容拷貝到另一個(gè)文件中

import shutil 
shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w')

shutil.copyfile(src, dst)
拷貝文件

shutil.copyfile('f1.log', 'f2.log') #目標(biāo)文件無(wú)需存在

shutil.copymode(src, dst)
僅拷貝權(quán)限难咕。內(nèi)容、組距辆、用戶均不變

shutil.copymode('f1.log', 'f2.log') #目標(biāo)文件必須存在

shutil.copystat(src, dst)
僅拷貝狀態(tài)的信息余佃,包括:mode bits, atime, mtime, flags

shutil.copystat('f1.log', 'f2.log') #目標(biāo)文件必須存在

shutil.copy(src, dst)
拷貝文件和權(quán)限

import shutil 
shutil.copy('f1.log', 'f2.log')

shutil.copy2(src, dst)
拷貝文件和狀態(tài)信息

import shutil
shutil.copy2('f1.log', 'f2.log')

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)

遞歸的去拷貝文件夾

import shutil 
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標(biāo)目錄不能存在,注意對(duì)folder2目錄父級(jí)目錄要有可寫(xiě)權(quán)限跨算,ignore的意思是排除 

shutil.rmtree(path[, ignore_errors[, onerror]])
遞歸的去刪除文件

import shutil 
shutil.rmtree('folder1')

shutil.move(src, dst)
遞歸的去移動(dòng)文件爆土,它類似mv命令,其實(shí)就是重命名诸蚕。

import shutil 
shutil.move('folder1', 'folder3')

shutil.make_archive(base_name, format,...)

創(chuàng)建壓縮包并返回文件路徑雾消,例如:zip、tar

創(chuàng)建壓縮包并返回文件路徑挫望,例如:zip立润、tar

  • base_name: 壓縮包的文件名,也可以是壓縮包的路徑媳板。只是文件名時(shí)桑腮,則保存至當(dāng)前目錄,否則保存至指定路徑蛉幸,
    如 data_bak =>保存至當(dāng)前路徑
    如:/tmp/data_bak =>保存至/tmp/
  • format: 壓縮包種類破讨,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要壓縮的文件夾路徑(默認(rèn)當(dāng)前目錄)
  • owner: 用戶奕纫,默認(rèn)當(dāng)前用戶
  • group: 組提陶,默認(rèn)當(dāng)前組
  • logger: 用于記錄日志,通常是logging.Logger對(duì)象
#將 /data 下的文件打包放置當(dāng)前程序目錄
import shutil
ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')   
#將 /data下的文件打包放置 /tmp/目錄
import shutil
ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data') 

六 json&pickle模塊

1.什么是序列化&反序列化

序列化 :將對(duì)象(變量)從內(nèi)存中變成可存儲(chǔ)或傳輸?shù)倪^(guò)程

反序列化:把變量?jī)?nèi)容從序列化的對(duì)象重新讀到內(nèi)存里

內(nèi)存中的數(shù)據(jù)類型---->序列化---->特定的格式(json格式或者pickle格式)

內(nèi)存中的數(shù)據(jù)類型<----反序列化<----特定的格式(json格式或者pickle格式)

# {'aaa':111}--->序列化str({'aaa':111})----->"{'aaa':111}"
a=str({'aaa':111})
print(a,type(a)) # {'aaa': 111} <class 'str'>
#{'aaa':111}<---反序列化eval("{'aaa':111}")<-----"{'aaa':111}"
b=eval(a)
print(b,type(b)) #{'aaa': 111} <class 'dict'>

2.為何要序列化

序列化得到結(jié)果=>特定的格式的內(nèi)容有兩種用途:

1.持久保存狀態(tài) (可用于存儲(chǔ)=》用于存檔)

2.跨平臺(tái)數(shù)據(jù)交互 (傳輸給其他平臺(tái)使用)

強(qiáng)調(diào):

針對(duì)用途1的特定一格式:是一種專用的格式=》pickle只有python可以識(shí)別

針對(duì)用途2的特定一格式:應(yīng)該是一種通用匹层、能夠被所有語(yǔ)言識(shí)別的格式=》json

3.如何序列化與反序列化

import json
# 序列化
json_res=json.dumps([1,'aaa',True,False])
print(json_res,type(json_res))
# [1, "aaa", true, false] <class 'str'>

# 反序列化
l=json.loads(json_res)
print(l,type(l))
# [1, "aaa", true, false] <class 'dict'>
import json
# 序列化的結(jié)果寫(xiě)入文件的復(fù)雜方法
json_res=json.dumps([1,'aaa',True,False])
with open('test.json','wt',encoding='utf-8') as f:
    f.write(json_res)
# 序列化的結(jié)果寫(xiě)入文件的簡(jiǎn)單方法
with open('test.json','wt',encoding='utf-8') as f:
    json.dumps([1,'aaa',True,False],f)
# 從文件讀取json格式的字符串進(jìn)行反序列化操作的復(fù)雜方法
with open('text.json','rt',encoding='utf-8') as f:
    json_res=f.read()
    l=json.loads(json_res)
    print(l,type(l))
    # [1, 'aaa', True, False] <class 'list'>
# 從文件讀取json格式的字符串進(jìn)行反序列化操作的簡(jiǎn)單方法
with open('text.json','rt',encoding='utf-8') as f:
    l=json.loads(f)
    print(l,type(l))
    # [1, 'aaa', True, False] <class 'list'>

json驗(yàn)證: json格式兼容的是所有語(yǔ)言通用的數(shù)據(jù)類型隙笆,不能識(shí)別某一語(yǔ)言的所獨(dú)有的類型

json.dumps({1,2,3,4,5})
# TypeError: Object of type set is not JSON serializable

json強(qiáng)調(diào):一定要搞清楚json格式,不要與python混淆

l=json.loads('[1,2,"aaa",true,false]')
#l=json.loads("[1,2,1.3,'aaa',true,false]") #json 不認(rèn)單引號(hào)
print(l[0]) #1

了解

l=json.loads(b'[1,"aaa",true,false]')
print(l,type(l))
# [1, 'aaa', True, False] <class 'list'>

with open('test.json',mode='rb') as f:
    l=json.load(f)

res=json.dumps({'name':'哈哈哈'})
print(res,type(res))
# {"name": "\u54c8\u54c8\u54c8"} <class 'str'>
res=json.loads('{"name": "\u54c8\u54c8\u54c8"}')
print(res,type(res))
# {'name': '哈哈哈'} <class 'dict'>

4.猴子補(bǔ)丁

猴子補(bǔ)丁的核心就是用自己的代碼替換所用模塊的源代碼
# 在入口處打猴子補(bǔ)丁
import json
import ujson
def monkey_patch_json():
    json.__name__ = 'ujson'
    json.dumps = ujson.dumps
    json.loads = ujson.loads
monkey_patch_json() # 在入口文件出運(yùn)行

# 后續(xù)代碼中的應(yīng)用
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.dumps()
# json.loads()
# json.loads()
# json.loads()

5.pickle模塊

import pickle
res=pickle.dumps({1,2,3,4,5})
print(res,type(res))
# b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8f\x94(K\x01K\x02K\x03K\x04K\x05\x90.'

s=pickle.loads(res)
print(s,type(s))
# {1, 2, 3, 4, 5} <class 'set'>

Pickle的問(wèn)題和所有其他編程語(yǔ)言特有的序列化問(wèn)題一樣,就是它只能用于Python撑柔,并且可能不同版本的Python彼此都不兼容瘸爽,因此,只能用Pickle保存那些不重要的數(shù)據(jù)铅忿,不能成功地反序列化也沒(méi)關(guān)系剪决。

七 shelve模塊(了解)

shelve模塊比pickle模塊簡(jiǎn)單,只有一個(gè)open函數(shù)檀训,返回類似字典的對(duì)象柑潦,可讀可寫(xiě);key必須為字符串,而值可以是python所支持的數(shù)據(jù)類型

import shelve

f=shelve.open(r'sheve.txt')
# f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']}
# f['stu2_info']={'name':'gangdan','age':53}
# f['school_info']={'website':'http://www.pypy.org','city':'beijing'}

print(f['stu1_info']['hobby'])
f.close()

八 xml模塊(了解)

xml是實(shí)現(xiàn)不同語(yǔ)言或程序之間進(jìn)行數(shù)據(jù)交換的協(xié)議峻凫,跟json差不多渗鬼,但json使用起來(lái)更簡(jiǎn)單

xml協(xié)議在各個(gè)語(yǔ)言里的都 是支持的,在python中可以用以下模塊操作xml:

# print(root.iter('year')) #全文搜索
# print(root.find('country')) #在root的子節(jié)點(diǎn)找蔚晨,只找一個(gè)
# print(root.findall('country')) #在root的子節(jié)點(diǎn)找乍钻,找所有
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,child.attrib['name'])
    for i in child:
        print(i.tag,i.attrib,i.text)
 
#只遍歷year 節(jié)點(diǎn)
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')
    node.set('version','1.0')
tree.write('test.xml')
 
 
#刪除node
for country in root.findall('country'):
   rank = int(country.find('rank').text)
   if rank > 50:
     root.remove(country)
 
tree.write('output.xml')

#在country內(nèi)添加(append)節(jié)點(diǎn)year2
import xml.etree.ElementTree as ET
tree = ET.parse("a.xml")
root=tree.getroot()
for country in root.findall('country'):
    for year in country.findall('year'):
        if int(year.text) > 2000:
            year2=ET.Element('year2')
            year2.text='新年'
            year2.attrib={'update':'yes'}
            country.append(year2) #往country節(jié)點(diǎn)下添加子節(jié)點(diǎn)

tree.write('a.xml.swap')

自己創(chuàng)建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) #生成文檔對(duì)象
et.write("test.xml", encoding="utf-8",xml_declaration=True)
 
ET.dump(new_xml) #打印生成的格式

九 configparser模塊

#文件text.ini內(nèi)容
[section1]
k1=v1
k2:v2
user=egon
age=18
is_admin=true
salary=31

[section2]
k1=v1
import configparser
config=configparser.ConfigParser()
config.read('text.ini')
# 1、獲取sections
print(config.sections()) #['section1', 'section2']
# 2铭腕、獲取某一section下的所有options
print(config.options(('section1'))) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
# 3银择、獲取items
print(config.items('section1')) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
# 4.查看標(biāo)題section1下user的值=>字符串格式
res=config.get('section1','user')
print(res,type(res)) # egon <class 'str'>
# 5.查看標(biāo)題section1下is_admin的值=>整數(shù)格式
res=config.getboolean('section1','is_admin')
print(res,type(res)) #True <class 'bool'>
# 6.查看標(biāo)題section1下age的值=>布爾值格式
res=config.getint('section1','age')
print(res,type(res)) #18 <class 'int'>
# 7.查看標(biāo)題section1下salary的值=>浮點(diǎn)型格式
res=config.getfloat('section1','salary')
print(res,type(res)) #31.0 <class 'float'>

改寫(xiě)

import configparser

config=configparser.ConfigParser()
config.read('a.cfg',encoding='utf-8')


#刪除整個(gè)標(biāo)題section2
config.remove_section('section2')

#刪除標(biāo)題section1下的某個(gè)k1和k2
config.remove_option('section1','k1')
config.remove_option('section1','k2')

#判斷是否存在某個(gè)標(biāo)題
print(config.has_section('section1'))

#判斷標(biāo)題section1下是否有user
print(config.has_option('section1',''))


#添加一個(gè)標(biāo)題
config.add_section('egon')

#在標(biāo)題egon下添加name=egon,age=18的配置
config.set('egon','name','egon')
config.set('egon','age',18) #報(bào)錯(cuò),必須是字符串


#最后將修改的內(nèi)容寫(xiě)入文件,完成最終的修改
config.write(open('a.cfg','w'))

十 hashlib模塊

1.什么是哈希hash

hash一類算法,該算法接受傳入的內(nèi)容累舷,經(jīng)過(guò)運(yùn)算得到一串hash值

hash值的特點(diǎn):

I 只要傳入的內(nèi)容一樣浩考,得到的hash值必然一樣
II 不能由hash值返解成內(nèi)容
III 不管傳入的內(nèi)容有多大,只要使用的hash算法不變被盈,得到的hash值長(zhǎng)度是一定

2.hash的用途

用途1:特點(diǎn)II用于密碼密文傳輸與驗(yàn)證

用途2:特點(diǎn)I析孽、III用于文件完整性校驗(yàn)

3.如何用

import hashlib
m=hashlib.md5()
m.update('hello'.encode('utf-8'))
m.update('world'.encode('utf-8'))
res=m.hexdigest()
print(res) #fc5e038d38a57032085441e7fe7010b0

m1=hashlib.md5('he'.encode('utf-8'))
m1.update('llo'.encode('utf-8'))
m1.update('wor'.encode('utf-8'))
m1.update('ld'.encode('utf-8'))
res=m1.hexdigest()
print(res) #fc5e038d38a57032085441e7fe7010b0

模擬撞庫(kù)破解密碼

import hashlib
passwds=[
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
    ]
def make_passwd_dic(passwds):
    dic={}
    for passwd in passwds:
        m=hashlib.md5(passwd.encode('utf-8'))
        dic[passwd]=m.hexdigest()
    return dic

def break_code(cryptograph,passwd_dic):
    for k,v in passwd_dic.items():
        if v == cryptograph:
            print('密碼是:%s' %k)
            

cryptograph='aee949757a2e698417463d47acac93df'
break_code(cryptograph,make_passwd_dic(passwds))

提升撞庫(kù)的成本=>密碼加鹽

import hashlib
m=hashlib.md5()
m.update('天王'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('蓋地虎'.encode('utf-8'))
print(m.hexdigest())

十一 subprocess模塊

import subprocess
obj=subprocess.Popen('echo 123 ; ls / ; ls /root',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,)
print(obj)
res=obj.stdout.read()
print(res) # b'123 ; ls / ; ls /root\r\n'
err_res=obj.stderr.read()
print(err_res.decode('utf-8'))

十二 logging模塊

1.日志級(jí)別與配置

import logging

# 一:日志配置
logging.basicConfig(
    # 1、日志輸出位置:1只怎、終端 2袜瞬、文件
    # filename='access.log', # 不指定,默認(rèn)打印到終端

    # 2身堡、日志格式
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',

    # 3邓尤、時(shí)間格式
    datefmt='%Y-%m-%d %H:%M:%S %p',

    # 4、日志級(jí)別
    # critical => 50
    # error => 40
    # warning => 30
    # info => 20
    # debug => 10
    level=30,
)

# 二:輸出日志
logging.debug('調(diào)試debug')
logging.info('消息info')
logging.warning('警告warn')
logging.error('錯(cuò)誤error')
logging.critical('嚴(yán)重critical')

'''
# 注意下面的root是默認(rèn)的日志名字
WARNING:root:警告warn
ERROR:root:錯(cuò)誤error
CRITICAL:root:嚴(yán)重critical
'''

2.日志配置字典

"""
logging配置
"""

import os

# 1贴谎、定義三種日志輸出格式汞扎,日志中可能用到的格式化串如下
# %(name)s Logger的名字
# %(levelno)s 數(shù)字形式的日志級(jí)別
# %(levelname)s 文本形式的日志級(jí)別
# %(pathname)s 調(diào)用日志輸出函數(shù)的模塊的完整路徑名,可能沒(méi)有
# %(filename)s 調(diào)用日志輸出函數(shù)的模塊的文件名
# %(module)s 調(diào)用日志輸出函數(shù)的模塊名
# %(funcName)s 調(diào)用日志輸出函數(shù)的函數(shù)名
# %(lineno)d 調(diào)用日志輸出函數(shù)的語(yǔ)句所在的代碼行
# %(created)f 當(dāng)前時(shí)間擅这,用UNIX標(biāo)準(zhǔn)的表示時(shí)間的浮 點(diǎn)數(shù)表示
# %(relativeCreated)d 輸出日志信息時(shí)的澈魄,自Logger創(chuàng)建以 來(lái)的毫秒數(shù)
# %(asctime)s 字符串形式的當(dāng)前時(shí)間。默認(rèn)格式是 “2003-07-08 16:49:45,896”仲翎。逗號(hào)后面的是毫秒
# %(thread)d 線程ID痹扇☆趵欤可能沒(méi)有
# %(threadName)s 線程名×庇可能沒(méi)有
# %(process)d 進(jìn)程ID票渠≈鸸可能沒(méi)有
# %(message)s用戶輸出的消息

# 2芬迄、強(qiáng)調(diào):其中的%(name)s為getlogger時(shí)指定的名字
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                  '[%(levelname)s][%(message)s]'

simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'

test_format = '%(asctime)s] %(message)s'

# 3、日志配置字典
LOGGING_DIC = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': standard_format
        },
        'simple': {
            'format': simple_format
        },
        'test': {
            'format': test_format
        },
    },
    'filters': {},
    'handlers': {
        #打印到終端的日志
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',  # 打印到屏幕
            'formatter': 'simple'
        },
        #打印到文件的日志,收集info及以上的日志
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志輪轉(zhuǎn)
            'formatter': 'standard',
            # 可以定制日志文件路徑
            # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目錄
            # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            'filename': 'a1.log',  # 日志文件
            'maxBytes': 1024*1024*5,  # 日志大小 5M
            'backupCount': 5,
            'encoding': 'utf-8',  # 日志文件的編碼昂秃,再也不用擔(dān)心中文log亂碼了
        },
        'other': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',  # 保存到文件
            'formatter': 'test',
            'filename': 'a2.log',
            'encoding': 'utf-8',
        },
    },
    'loggers': {
        #logging.getLogger(__name__)拿到的logger配置
        '': {
            'handlers': ['default', 'console'],  # 這里把上面定義的兩個(gè)handler都加上禀梳,即log數(shù)據(jù)既寫(xiě)入文件又打印到屏幕
            'level': 'DEBUG', # loggers(第一層日志級(jí)別關(guān)限制)--->handlers(第二層日志級(jí)別關(guān)卡限制)
            'propagate': False,  # 默認(rèn)為T(mén)rue,向上(更高level的logger)傳遞肠骆,通常設(shè)置為False即可算途,否則會(huì)一份日志向上層層傳遞
        },
        '專門(mén)的采集': {
            'handlers': ['other',],
            'level': 'DEBUG',
            'propagate': False,
        },
    },
}

3.使用

import settings

# !!!強(qiáng)調(diào)!!!
# 1、logging是一個(gè)包蚀腿,需要使用其下的config嘴瓤、getLogger,可以如下導(dǎo)入
# from logging import config
# from logging import getLogger

# 2莉钙、也可以使用如下導(dǎo)入
import logging.config # 這樣連同logging.getLogger都一起導(dǎo)入了,然后使用前綴logging.config.

# 3廓脆、加載配置
logging.config.dictConfig(settings.LOGGING_DIC)

# 4、輸出日志
logger1=logging.getLogger('用戶交易')
logger1.info('egon兒子alex轉(zhuǎn)賬3億冥幣')

# logger2=logging.getLogger('專門(mén)的采集') # 名字傳入的必須是'專門(mén)的采集'磁玉,與LOGGING_DIC中的配置唯一對(duì)應(yīng)
# logger2.debug('專門(mén)采集的日志')

十三 re模塊

1.什么是正則

正則就是用一些具有特殊含義的符號(hào)組合到一起(稱為正則表達(dá)式)來(lái)描述字符或者字符串的方法停忿。或者說(shuō):正則就是用來(lái)描述一類事物的規(guī)則蚊伞。

(在Python中)它內(nèi)嵌在Python中席赂,并通過(guò) re 模塊實(shí)現(xiàn)。正則表達(dá)式模式被編譯成一系列的字節(jié)碼时迫,然后由用 C 編寫(xiě)的匹配引擎執(zhí)行颅停。

2.常用匹配模式(元字符)

import re
# w與W
print(re.findall('\w','aAbc123_*()-='))
# ['a', 'A', 'b', 'c', '1', '2', '3', '_']
print(re.findall('\W',' aAbc123_*()-= '))
# [' ', '*', '(', ')', '-', '=', ' ']

#s與S
print(re.findall('\s','aA\rbc\t\n12\f3_*()-= ')) ##\n \t都是空,都可以被\s匹配
# ['\r', '\t', '\n', '\x0c', ' ']
print(re.findall('\S','aA\rbc\t\n12\f3_*()-= '))
# ['a', 'A', 'b', 'c', '1', '2', '3', '_', '*', '(', ')', '-', '=']

#\n與\t
print(re.findall(r'\n','hello egon \n123')) #['\n']
print(re.findall(r'\t','hello egon\t123')) #['\t']

#d與D
print(re.findall('\d','aA\rbc\t\n12\f3_*()-= ')) 
# ['1', '2', '3']
print(re.findall('\D','aA\rbc\t\n12\f3_*()-= '))
# ['a', 'A', '\r', 'b', 'c', '\t', '\n', '\x0c', '_', '*', '(', ')', '-', '=', ' ']

#A與Z
print(re.findall('\Aalex','alexis alex sb')) #['alex']  #\A==>^
print(re.findall('\Aalex',' alexis alex sb')) #[]
print(re.findall('sb\Z',' alexis alexsb sb')) #['sb']   #\Z==>$
print(re.findall('sb\Z',' alexis alexsb sb '))  #[]

#^與$
print(re.findall('sb$','alexis alexsb sb'))  #['sb']
print(re.findall('^alex','alexis alexsb sb'))  #['alex']
print(re.findall('sb$',"""alex
alexis
alex
sb
"""))
# ['sb']
print(re.findall('^alex$','alexis alex sb')) #[]
print(re.findall('^alex$','al       ex')) #[]
print(re.findall('^alex$','alex')) #['alex']

重復(fù)匹配:| . | * | ? | .* | .*? | + | {n,m} |
1、.:匹配除了\n之外任意一個(gè)字符掠拳,指定re.DOTALL之后才能匹配換行符
print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b'))
# ['a1b', 'a2b', 'a b', 'abb', 'a\tb', 'a*b']
print(re.findall('a.b','a1b a2b a b abbbb a\nb a\tb a*b',re.DOTALL))
# ['a1b', 'a2b', 'a b', 'abb', 'a\nb', 'a\tb', 'a*b']

2癞揉、*:左側(cè)字符重復(fù)0次或無(wú)窮次,性格貪婪
print(re.findall('ab*','a ab abb abbbbbbbb bbbbbbbb'))
# ['a', 'ab', 'abb', 'abbbbbbbb']

3碳想、+:左側(cè)字符重復(fù)1次或無(wú)窮次烧董,性格貪婪
print(re.findall('ab+','a ab abb abbbbbbbb bbbbbbbb'))
# ['ab', 'abb', 'abbbbbbbb']

4.?:左側(cè)字符重復(fù)0次或1次
print(re.findall('ab?','a ab abb abbbbb bbbbbb'))
#['a', 'ab', 'ab', 'ab']

5、{n,m}:左側(cè)字符重復(fù)n次到m次
# {0,} => *
# {1,} => +
# {0,1} => ?
# {n}單獨(dú)一個(gè)n代表只出現(xiàn)n次胧奔,多一次不行少一次也不行
print(re.findall('ab{2,5}','a ab abb abbb abbbb abbbbbbbb bbbbbbbb'))
# ['abb','abbb','abbbb','abbbbb']

# 取出小數(shù)和整數(shù)
print(re.findall('\d+\.?\d*',"asdfasdf123as1111111.123dfa12adsf1asdf3"))
# ['123', '1111111.123', '12', '1', '3']
[]匹配指定字符一個(gè)
print(re.findall('a\db','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL))
# ['a3b', 'a4b', 'a9b']
print(re.findall('a[501234]b','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL))
# ['a3b','a4b']
print(re.findall('a[0-5]b','a1111111b a3b a4b a9b aXb a b a\nb',re.DOTALL))
#['a3b', 'a1b', 'a0b', 'a4b']
print(re.findall('a[0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL))
# ['axb', 'a3b', 'a1b', 'a0b', 'a4b', 'a9b', 'aXb']
print(re.findall('a[^0-9a-zA-Z]b','a1111111b axb a3b a1b a0b a4b a9b aXb a b a\nb',re.DOTALL))# []內(nèi)的^代表的意思是取反
# ['a b','a/nb']
print(re.findall('a-b','a-b aXb a b a\nb',re.DOTALL))
# ['a-b']
print(re.findall('a[-0-9\n]b','a-b a0b a1b a8b aXb a b a\nb',re.DOTALL))
#['a-b','a0b','a1b','a8b','a\nb']

1

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逊移,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌矛缨,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萄焦,死亡現(xiàn)場(chǎng)離奇詭異扇商,居然都是意外死亡凤瘦,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)案铺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蔬芥,“玉大人,你說(shuō)我怎么就攤上這事控汉”仕校” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵姑子,是天一觀的道長(zhǎng)乎婿。 經(jīng)常有香客問(wèn)我,道長(zhǎng)街佑,這世上最難降的妖魔是什么谢翎? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮沐旨,結(jié)果婚禮上森逮,老公的妹妹穿的比我還像新娘。我一直安慰自己希俩,他們只是感情好吊宋,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著颜武,像睡著了一般璃搜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鳞上,一...
    開(kāi)封第一講書(shū)人閱讀 49,929評(píng)論 1 290
  • 那天这吻,我揣著相機(jī)與錄音,去河邊找鬼篙议。 笑死唾糯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的鬼贱。 我是一名探鬼主播移怯,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼这难!你這毒婦竟也來(lái)了舟误?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姻乓,失蹤者是張志新(化名)和其女友劉穎嵌溢,沒(méi)想到半個(gè)月后眯牧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡赖草,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年学少,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秧骑。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡版确,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腿堤,到底是詐尸還是另有隱情阀坏,我是刑警寧澤如暖,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布笆檀,位于F島的核電站,受9級(jí)特大地震影響盒至,放射性物質(zhì)發(fā)生泄漏酗洒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一枷遂、第九天 我趴在偏房一處隱蔽的房頂上張望樱衷。 院中可真熱鬧,春花似錦酒唉、人聲如沸矩桂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)侄榴。三九已至,卻和暖如春网沾,著一層夾襖步出監(jiān)牢的瞬間癞蚕,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工辉哥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桦山,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓醋旦,卻偏偏與公主長(zhǎng)得像恒水,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子饲齐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容