Python学习笔记第五周
目錄
一、基礎概念
1、模塊定義
2、包的定義
3、導入包的本質
4、導入模塊的本質
5、導入方法
6、import的本質
7、導入優化
8、模塊分類
9、標準庫介紹
1、time與datetime
2、random模塊
3、os模塊
4、sys模塊
5、shutil模塊
6、shelve模塊
7、XML模塊
8、Pyyaml模塊
9、configParser模塊
10、hashlib模塊
11、re模塊
12、collections模塊
13、subprocess模塊
14、logging模塊
10、二分法
11、冒泡排序
12、時間復雜度
13、深拷貝
?
一、基礎概念:
1、模塊定義
本質就是.py結尾的python文件(文件名:test.py 對應模塊名: test),用來從邏輯上組織python代碼(變量、函數、類、邏輯)
2、包的定義
用來從邏輯上組織模塊的,本質就是一個目錄(必須帶有一個名字叫__init__.py的文件)
3、導入包的本質
執行包目錄下所在的__init__.py文件
4、導入模塊的本質
將該模塊的python文件在導入的程序中通過解釋器去解釋一遍
5、導入方法
1、import module_name
2、import module_name1,module_name2.....
3、from module_name import func_name (as ? func1_name) ?#可以對導入的函數起別名,為了避免與本文件的函數重名導致功能沒法實現
?
6、import的本質
導入模塊本質就是找到這個文件,并且把python文件解釋一遍,其中import test 表示 ? ?test=‘test.py ? all code’ ?把該test.py文件全部解釋一遍,而from test import m m=‘test.py about m code’ ?表示從test.py文件中取出關于m的代碼在本文件中解釋一遍
?
7、導入優化
通常情況下,使用import module_name 如果在其中總是使用test函數,這樣每次在使用時會實現檢查test函數在module_name模塊中是否存在,為了提高效率,可以使用from module_name import test方法導入該函數,相當于直接將test函數在這里直接解釋了一編,提高運行效率
?
8、模塊分類
1、標準庫也叫內置模塊
2、開源模塊也叫第三方模塊
3、自定義模塊
9、標準庫介紹
1、time與datetime
時間戳,以秒為單位
time.time()函數,以秒來計算
print(time.time()) #time.time不需要提供任何參數,表示自1970年1月1日到現在經過多少秒 #輸出: 1487733672.621412
元組方式表示時間struct_time,包括了9個元素
time.localtime()#如果里面沒有提供任何參數,會表示當前時間, 如果里面提供已秒為單位的數字,會顯示對應其對應時間
print(time.localtime()) #輸出 time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=14, tm_min=34, tm_sec=7, tm_wday=2, tm_yday=53, tm_isdst=0)#其中wday代表本周第幾天,yday代表本年的第幾天,而lsdst代表夏令時 #DST:夏令時 #UTC:世界標準時間
time.timezone #以秒的格式表示時區
print(time.timezone) #輸出 -28800 #28800/3600=8表示東八區
time.daylight#是否使用夏令時
print(time.daylight) #輸出 0
time.sleep()#其中跟參數表示暫停運行幾秒
time.sleep(3)
time.gmtime與locatime
兩者都是表示以元組形式表示時間,同時都以秒為所傳參數,其中gmtime表示UTC時間,而localtime表示本地時間
print(time.gmtime()) print(time.gmtime(394049430)) #輸出 time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=6, tm_min=53, tm_sec=56, tm_wday=2, tm_yday=53, tm_isdst=0) time.struct_time(tm_year=1982, tm_mon=6, tm_mday=27, tm_hour=18, tm_min=10, tm_sec=30, tm_wday=6, tm_yday=178, tm_isdst=0)
print(time.localtime()) print(time.localtime(394049430)) #輸出 time.struct_time(tm_year=2017, tm_mon=2, tm_mday=22, tm_hour=14, tm_min=54, tm_sec=57, tm_wday=2, tm_yday=53, tm_isdst=0) time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=0)
x = time.localtime() print(x.tm_year) #同理,在得到的strcut_time中可以根據參數取不同的值 #輸出 2017
?
time.mktime()#直接傳入元組的形式,變為對應的秒
x = time.localtime(394049430) print(x) print(time.mktime(x)) #通過傳入已元組形式的時間,轉換成對應的秒 #輸出 time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=0) 394049430.0
time.strftime()#將struct_time轉成格式化的時間字符串
?
x = time.localtime(394049430) print(time.strftime('%Y-%m-%d %H:%M:%S', x))#%Y代表四位的年,%y代表兩位表示的年,%m代表月,%M代表分鐘,%H代表小時,%S代表秒 %w代表這種的第幾天 #輸出 1982-06-28 02:10:30
time.strptime()#將格式化的時間字符串轉成struct_time
x = time.localtime(394049430) y = time.strftime('%y-%m-%d %H:%M:%S', x) print(time.strptime(y,'%%m-%d %H:%M:%S'))# 前面為格式化的時間字符串,后面是對應的格式,可以將該格式化時間字符串變為struct_time元組,格式只要匹配就可以,沒有順序要求例如:time.strptime("02-20 14:08:34 2017", "%m-%d %H:%M:%S %Y")
#輸出 time.struct_time(tm_year=1982, tm_mon=6, tm_mday=28, tm_hour=2, tm_min=10, tm_sec=30, tm_wday=0, tm_yday=179, tm_isdst=-1)
strftime('格式',struct_time(元組格式)) ?--->轉換成格式化時間字符串
strptime('格式化時間字符串',‘格式’) ?-----> 轉成成struct_time
?
轉換關系:
時間戳轉成struct_time:gmtime、localtime
struct_time轉成時間戳:mktime
struct_time轉成格式化時間字符串:strftime
格式化時間字符串轉成struct_time:strptime
?
time.asctime()#將struct_time轉成格式化時間字符串,格式為%a %b %d? %H:%M:%S %Y,其中%a表示星期,%b表示月,如果asctime沒有傳遞參數,默認會導入localtime()的結果
print(time.asctime()) x = time.localtime(394049430) print(time.asctime(x)) #輸出 Wed Feb 22 15:44:21 2017 Mon Jun 28 02:10:30 1982
?
time.ctime()將時間戳轉成為%a?%b %d? %H:%M:%S %Y,其中%a表示星期,%b表示月
print(time.ctime()) #如果沒參數傳遞,會將locatime轉成成的秒傳進去 x = time.time() print(time.ctime(x)) #傳遞進來的是時間戳,為秒 #輸出 Wed Feb 22 15:48:25 2017 Wed Feb 22 15:48:25 2017
?
datetime模塊:
datetime.datetime.now()#獲取當前時間
print(datetime.datetime.now()) #輸出 2017-02-22 15:52:24.551932
datetime.datetime.now()+datetime.timedelta(3) #默認是三天后的時間
print(datetime.datetime.now()+datetime.timedelta(3)) #輸出 2017-02-25 15:54:03.199349
datetime.datetime.now()+datetime.timedelta(-3)#三天前的時間
print(datetime.datetime.now()+datetime.timedelta(-3)) #輸出 2017-02-19 15:54:59.262861
? datetime.datetime.now()+datetime.timedelta(hours=3)#三小時后的時間
print(datetime.datetime.now()+datetime.timedelta(hours=3)) #輸出 2017-02-22 19:04:30.683096
datetime.datetime.now()+datetime.timedelta(hours=-3)#三小時前的時間
print(datetime.datetime.now()+datetime.timedelta(hours=-3)) #輸出 2017-02-22 13:05:11.410832
當前時間替換time.replace()
c_time= datetime.datetime.now() print(c_time)r_time = c_time.replace(minute=3,hour=2) print(r_time) #輸出 2017-02-22 16:08:55.694556 2017-02-22 02:03:55.694556
?
?
2、random模塊
import randomprint(random.random()) #random()函數會在0-1之間隨機取值 #輸出 0.28605143730067417print(random.randint(1,3)) #從整數中隨機取值,得到的值均為1-3之間,1和3均有機會取到 #輸出 3print(random.randrange(1,3))#隨機取1-2的整數,不會取到3 #輸出 2print(random.choice('abcde')) #choice表示從序列中取值,序列包括字符串 元組 列表 字典 #輸出 #b print(random.choice([4,3,2,4])) #輸出 3 print(random.choice((4,3,2,4))) #輸出 4print(random.sample('hello word',4)) #隨機取四個數字 #輸出 #['r', 'l', 'w', 'h']print(random.uniform(1,3)) #手工設置random.random的取值范圍,默認只是0-1之間,通過uniform方法可以做到在任意范圍 #輸出 2.07789196870395item = [1,2,3,4,5,6,7,8] random.shuffle(item) print(item) #輸出 [5, 2, 3, 8, 6, 4, 1, 7]
例子:
驗證碼
?
import randomcheckcode = ''for i in range(1,6):x = random.randint(0,9) #取0-9隨機數if x == i:x = chr(random.randint(65,90)) #將隨機取一個數字然后轉換成ascii碼else:x = random.randint(0,9)checkcode += str(x) #添加x到字符串中 print(checkcode)
?
3、os模塊
>>> import os >>> os.getcwd() #獲取當前路徑 '/Users/Gavin' >>> os.chdir('/Users') #修改當前路徑 >>> os.getcwd() '/Users' >>> os.curdir #獲取當前目錄 '.' >>> os.pardir #獲取上一級目錄 '..' >>> os.makedirs('/Users/Gavin/Desktop/a/b/c') #創建目錄,就算沒有父級目錄頁會遞歸創建 >>> os.removedirs('/Users/Gavin/Desktop/a/b/c')#刪除目錄,如果父集目錄沒有文件也會隨之刪除 os.mkdir('/Users/Gavin/Desktop/a/b/c')#如果創建的目錄中沒有父集目錄會報錯 Traceback (most recent call last):File "<stdin>", line 1, in <module> FileNotFoundError: [Errno 2] No such file or directory: '/Users/Gavin/Desktop/a/b/c' >>>os.mkdir('/Users/Gavin/Desktop/a') >>>os.rmdir('/Users/Gavin/Desktop/a')#刪除創建的目錄 >>>os.listdir('/Users/Gavin/Desktop')#列出目錄中的文件以及子目錄 >>>os.remove('/Users/Gavin/Desktop/??兩??網?合?1并.xlsx')#刪除對應的文件 >>>os.rename('/Users/Gavin/Desktop/oldname.doc','/Users/Gavin/Desktop/newname.doc')#修改文件名 >>>os.stat('/Users/Gavin/Desktop/newname.doc') os.stat_result(st_mode=33152, st_ino=40047776, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=116224, st_atime=1487753837, st_mtime=1487753837, st_ctime=1487753837) >>> os.sep #顯示特定系統的目錄分隔符 '/' >>> os.linesep #顯示特定系統的換行符 '\n' >>> os.pathsep#顯示特定系統的路徑分隔符 ':'os.environ #顯示環境變量 environ({'SHELL': '/bin/bash', 'SHLVL': '1', 'PWD': '/Users/Gavin', 'TMPDIR'}) >>> os.name 'posix' os.system('ls -l') #執行系統bash命令 total 2992 drwx------ 3 Gavin staff 102 10 29 11:42 Applications drwx------+ 35 Gavin staff 1190 2 22 22:10 Desktop >>> os.path.abspath('__file__') #查找文件的絕對路徑 '/Users/Gavin/__file__' >>> os.path.split('/Users/Gavin') #os.path.split會將字符串通過/分割為兩部分,不管文件或者路徑是否存在 ('/Users', 'Gavin') >>> os.path.split('a/b') ('a', 'b') >>> os.path.dirname(os.path.abspath('__file__')) #os.path.dirname顯示文件所在路徑 '/Users/Gavin' >>> os.path.basename(os.path.abspath('__file__')) #os.path.basename只顯示文件名 '__file__' >>> os.path.exists('/Users/Gavin') #os.path.exists判斷文件或者目錄是否存在 True >>> os.path.exists('/Users/a') False >>> os.path.isfile('/Users/Gavin/Desktop/newname.doc') #判斷是否為文件 True >>> os.path.isfile('/Users/Gavin/Desktop/oldboy') False >>> os.path.isfile('/Users/Gavin/Desktop/oa') #就算不存在也不會報錯只不過顯示不為文件 False >>> os.path.isdir('/Users/Gavin/Desktop/oa') #判斷目錄是否為目錄,不存在也不會報錯 False >>> os.path.isdir('/Users/Gavin/Desktop') #判斷是否為目錄 True >>> os.path.join('a','b') #將前面兩個字符串通過/方式合并 'a/b' >>> os.path.join('/Users','Gavin') '/Users/Gavin' >>> os.path.getatime('/Users/Gavin') #目錄或者文件的訪問時間 1487772945.0 >>> os.path.getctime('/Users/Gavin') #目錄或者文件的創建時間 1486950756.0
?
4、sys模塊
>>> sys.version #顯示python版本號 '3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25) \n[GCC 4 vim sys-test.py import sys print(sys.argv[1]) print(sys.argv[2]) >>>python3 sys-test.py a b a b >>>sys.exit(1) #退出,默認情況下正常退出為0
?
5、shutil模塊
進行高級的文件、文件夾的拷貝工作,還可以壓縮包
? shutil.copyfileobj(src_file,dest_file) #拷貝文件,不常用,因為沒有流控制
import shutilsource_file= open('本節筆記','r',encoding='utf-8') dest_file = open('本節拷貝','w',encoding='utf-8') shutil.copyfileobj(source_file,dest_file)
shutil.copyfile(src_file,dest_file)#拷貝文件,copyfile比copyfileobj多了with open file as f這個步驟,所以無需使用source_file ?和dest_file這兩個變量代替引用
shutil.copyfile('本節筆記','本節拷貝') #源文件存在,目標文件可以存在,也可以不存在
shutil.copymode(src_file,dest_file) #只拷貝權限,內容,組、用戶都不變
shutil.copymode('本節筆記','本節拷貝') #目標文件需要存在,只拷貝權限
shutil.copystat(src_file,dest_file)#拷貝狀態的信息,包括:mode bits, atime, mtime, flags
shutil.copymode('本節筆記','本節拷貝') #目標文件需要存在,只拷貝權限
shutil.copy(src_file,dest)#copy比copyfile更高明的一點就是在于dest就算是目錄,copy動作也會成功,同時會在dest的目錄下創建一個和src_file完全相同的文件名,比copyfile多了copymode方法
shutil.copy('本節筆記','/Users/Gavin/PycharmProjects/python/day5/test')
shutil.copy2(src_file,dest)#copy2和copy類似,和copy的區別在于不是調用copymode,而是調用copystat函數
shutil.copy2('本節筆記','/Users/Gavin/PycharmProjects/python/day5')
shutil.copytree('src_dict','dest_dict') #copytree是目錄拷貝,將源目錄所有文件和目錄全部拷貝到目標目錄,有個必須注意的地方在于dest_dict目錄必須是不存在的,如果存在就會報錯
shutil.copytree('/Users/Gavin/Desktop/a','/Users/Gavin/Desktop/k')
shutil.rmtree('目錄')#rmtree會遞歸方式刪除相應目錄
shutil.rmtree('/Users/Gavin/Desktop/a')
shutil.move(src_dict,dest_dict)#將a目錄更名為b目錄,如果在不同路徑下,就完成移動動作
shutil.move('/Users/Gavin/Desktop/a','/Users/Gavin/Desktop/b')
? shutil.make_archive(base_name,format,root=dir='')?
shutil.make_archive('/Users/Gavin/Desktop/b/desktop','zip',root_dir='/Users/Gavin/Desktop/b') '''第一個參數表示base_name即壓縮后的名字,后綴名會自動添加為第二個參數也就是壓縮的方法包括:bztar,gztar,tar,xztar,zip等方法可選,root_dir表要壓縮 目錄或者文件,總體來講,第一個是壓縮后的basename,如果第一個參數只寫了名字而沒有寫目錄,會將壓縮包保存到當前目錄然后添加后面第二個參數為擴展名,第三個參數表示要壓縮的目錄或者文件''' print(shutil.get_archive_formats()) #表示壓縮打包包括哪幾種方法,如果忘記可以通過該函數進行查詢
補充說明:
shutil對壓縮包的調用ZipFile和TarFile兩個模塊完成的
a) ZipFile函數
import zipfile #壓縮 z = zipfile.ZipFile('壓縮名.zip','w') #壓縮文件 z.write('本節筆記') #要壓縮的文件添加 z.write('本節拷貝') #要壓縮的文件添加 z.close()
#解壓
z = zipfile.ZipFile('壓縮名.zip','r')
z.extractall() #將壓縮文件解壓
z.close()
b) TarFile
import tarfile #打包 tar = tarfile.open('tar.tar','w') tar.add('本節筆記.zip',arcname='本節筆記.zip') #tar.add('本節拷貝',arcname='本節拷貝.zip') tar.close() #解包 tar = tarfile.open('tar.tar','r') tar.extractall() tar.close()
?
?
6、shelve模塊
一個簡單的k,v 將內存數據通過持久化的模塊,可以持久任何pickle可支持python數據格式
import shelve,datetimeinfo = {'name':'gavin', 'age': 16 ,'job': 'IT'} name1 = [1,2,3,4,5] name2 = 'abededg' time_now = datetime.datetime.now() #持久化存儲 with shelve.open('shelve_test',) as f: #通過shelve.open方式打開文件,不需要寫w和rf['info'] = info #將需要持久化的數據導入shelve_test中保存f['name1'] = name1f['name2'] = name2f['time_now'] = time_now#從文件中讀取 with shelve.open('shelve_test',) as f:print(f.get('name1')) #通過k方式獲取valueprint(f.get('info'))print(f.get('name2'))print(f.get('time_now'))
?
7、XML模塊
xml是實現不同語言或程序之間進行數據交換的協議,跟json差不多,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,大家只能選擇用xml呀,至今很多傳統公司如金融行業的很多系統的接口還主要是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>
xml協議在各個語言里的都 是支持的,在python中可以用以下模塊操作xml
import xml.etree.ElementTree as ETtree = 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)
修改和刪除xml文檔內容
import xml.etree.ElementTree as ETtree = ET.parse("xmltest.xml") root = tree.getroot()#修改 for node in root.iter('year'):new_year = int(node.text) + 1node.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')
自己創建xml文檔
import xml.etree.ElementTree as ETnew_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) #打印生成的格式
?
8、Pyyaml模塊
Python也可以很容易的處理ymal文檔格式,只不過需要安裝一個模塊,參考文檔:http://pyyaml.org/wiki/PyYAMLDocumentation?
?
9、configParser模塊
用于生成和修改常見配置文檔,當前模塊的名稱在 python 3.x 版本中變更為 configparser。
a)生成config文件
import configparserconfig = configparser.ConfigParser()config['DEFAULT'] = {'ServerAliveInterval': '45','Compresssion': 'yes','CompressionLevel': '9' }config['bitbucket.org'] = {} bitbucket = config['bitbucket.org'] bitbucket['User'] = 'hg' config['topsercret.server.com'] = {} topsercert = config['topsercret.server.com'] topsercert['Host Port'] = '50022' topsercert['ForwardX11'] = 'no' config['DEFAULT']['ForwardX11'] = 'yes' with open('example.ini', 'w') as f:config.write(f) #輸出 [DEFAULT] serveraliveinterval = 45 compressionlevel = 9 compresssion = yes forwardx11 = yes[bitbucket.org] user = hg[topsercret.server.com] host port = 50022 forwardx11 = no
?
b)讀配置文件
import configparserconfig = configparser.ConfigParser()print(config.sections()) #開始沒有讀進來之前沒法看到sections config.read('example.ini')print(config.sections()) #通過sections函數沒法讀到default內容 conf_default = config.defaults() for line in conf_default:print('%s:\t%s' %(line,conf_default[line]))print(config['bitbucket.org']['User'])if 'bitbucket.org' in config:print(True)topsecert = config['topsercret.server.com'] print(topsecert['Host Port']) for key in config['bitbucket.org']:print(key) #輸出 [] ['bitbucket.org', 'topsercret.server.com'] serveraliveinterval: 45 compressionlevel: 9 compresssion: yes forwardx11: yes hg True 50022 user serveraliveinterval compressionlevel compresssion forwardx11
?
c)修改配置文件
import configparserconfig = configparser.ConfigParser()config.read('example.ini')#讀取 secs = config.sections() print(secs)options = config.options('bitbucket.org') #單獨針對調用某一section對應的配置選項,options選項會將default選項內容帶入 print(options)item_list= config.items('bitbucket.org') #針對調用section中對應的配置選項已經對應參數,item選項會將default選項也帶入 print(item_list)val = config.get('bitbucket.org','user') print(val) val = config.get('bitbucket.org','compresssion') print(val)#修改 sec = config.remove_section('bitbucket.org') #移除secion sec = config.add_section('DB') #添加section sec = config.has_section('DB') #判斷section是否存在 print(sec) sec = config.has_option('topsercret.server.com','forwardx11') #判斷section中的option是否存在 print(sec)config.set('DB','mysql','https://www.mysql.com/3306') #對section中的option添加參數,必須為str類型 config.remove_option('topsercret.server.com','Host Port') #移除section內option with open('example1.ini','w') as f:config.write(f) #輸出 [DEFAULT] serveraliveinterval = 45 compressionlevel = 9 compresssion = yes forwardx11 = yes[topsercret.server.com] forwardx11 = no[DB] mysql = https://www.mysql.com/3306
?
10、hashlib模塊
用于加密相關的操作,3.x里代替了md5模塊和sha模塊,主要提供?SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlibm = hashlib.sha512() #hashlib還包括md5 sha1等不同安全等級的函數調用 m.update('hello'.encode(encoding='utf-8'))print(m.hexdigest()) #按照16進制格式顯示 m.update('中文也可以加密'.encode(encoding='utf-8')) print(m.hexdigest())m1 = hashlib.sha512() m1.update('hello中文也可以加密'.encode(encoding='utf-8')) print(m1.hexdigest())m2 = hashlib.sha512() with open('config.cfg','r') as f:f1 = f.read()m2.update('f1'.encode(encoding='utf-8')) #可以將整個文件進行加密 print(m2.hexdigest()) #輸出 9b71d224bd62f3785d96d46ad3ea3d73319bfbc2890caadae2dff72519673ca72323c3d99ba5c11d7c7acc6e14b8c5da0c4663475c2e5c3adef46f73bcdec043 9600f16b6ac743e6a78557de89b458f9c373424d8762ed4730397148e5f352d0339e879786fd0404635c907503f7a73ae70ea9be82dbcf9a1c66cc77f33690de 9600f16b6ac743e6a78557de89b458f9c373424d8762ed4730397148e5f352d0339e879786fd0404635c907503f7a73ae70ea9be82dbcf9a1c66cc77f33690de bc07fac547256ebcf7abc70731753f4ba70d4c09d856fab4f89255787bde9cbadc2ab85a77dcbbb523a7acf818bdf8db2da5ffb9b1a4d2b4ad71810795d3a546
python 還有一個 hmac 模塊,它內部對我們創建 key 和 內容 再進行處理然后再加密
?
import hmach = hmac.new('中文key也可以'.encode(encoding='utf-8'),'message也是可以是中文'.encode(encoding='utf-8')) #前面是key,后面mess,在后面可以使用加密方法,但是一直沒有使用過 h.update('我們在奮斗的路上一直不停留'.encode(encoding='utf-8')) print(h.hexdigest()) #輸出 749c771880c1cf952c957623605918d8
?
11、re模塊
常用的正則表達式符號
'.' 默認匹配除了\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
’^‘ 匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r'^a', '\nabc\necc',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次
’{m,n}‘ 匹配前一個字符m到n次,re.findall('ab{1,3}', 'abb abc abbcbbb') 結果['abb', 'ab', abb]
? ? ? ? '|' 匹配|左或|右的字符,re.search('ab|ABC','ABCBabcCD') 結果['ABC']
(...) 分組匹配,re.search('(abc){2}a(123|456)c', 'abcabca456c').group() 結果 ?abcabca456c
\A ? 只從字符開頭匹配,re.search('\Aabc', 'alexabc') 是匹配不到的,\A == ?^
\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
\b 類似與bash中\< ? ? ?\>對單詞做錨定
? ? ? (?P<name>....) 分組匹配re.search(’(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<hometown>[0-9{2}])(?P<birthday>[0-9]{8})‘, '
371481199306143242').groupdict() ? 結果是{’province‘: 37, 'city': 14, 'hometown': 81,'birthday': 19930614}
?
最常用的匹配語法
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符當做列表分隔符
re.sub 匹配字符并替換 僅需輕輕知道的幾個匹配模式
re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同) M(MULTILINE): 多行模式,改變'^'和'$'的行為(參見上圖) S(DOTALL): 點任意匹配模式,改變'.'的行為
?
import reMatch = re.search(r'\ber\b', ' i am er eraber') print(Match.group()) #輸出 era = re.match('chen', 'chenronghuachenronghua') #有返回就是匹配到了,match從開頭匹配 print(a.group()) #輸出 chena = re.match('k', 'chenronghuachenronghua') print(a) #匹配不到,如果寫a.group()會報錯 匹配不到a = re.match('chen\d', 'chen234ronghua1234chenronghua12431adec') #有返回就是匹配到了 print(a.group()) #輸出 chen2 \d代表數字,匹配一次,如果表示一個或多個,使用\d+a = re.match('.+', 'chen234ronghua1234chenronghua12431adec') #有返回就是匹配到了 print(a.group()) #輸出 chen234ronghua1234chenronghua12431adeca = re.search('^chen', 'chen234ronghua1234ronghua12431adec') #匹配所有,但是找到第一個就返回 print(a.group()) #輸出 chena = re.search('^c.+n\d+', 'chen234ronghua1234ronghua12431adec') #已c開頭,中間用多個任意字符,后面是一個數字\d,因為使用search所以只能匹配第一個匹配就返回 print(a.group()) #輸出 chen234 a = re.findall('^c.+n\d+', 'chen234ronghua1234ronghua12431adec') #findall會匹配全部匹配到值 print(a) #輸出['chen234']a = re.findall('\+$', 'chen234ronghua1234ronghua12431adec') #findall會匹配全部匹配到值D \D表示匹配非數字但是會匹配特殊字符 print(a) #輸出 ['adec']a = re.search('a[a-zA-Z]+c$', 'chen234ronghua1234ronghua12431adec') #[a-zA-Z]表示匹配所有字符一次,加+表示1次到多次 print(a.group()) #輸出 adec a = re.search(r'\b#.+#$', '1123#hello#') #\b表示錨定字符 print(a.group()) #輸出#hello# a = re.findall(r'a?', 'abaalexa') # ?表示匹配前面字符0-1次 print(a) #輸出 ['a', '', 'a', 'a', '', '', '', 'a', '']a = re.search('[0-9]{3}','aa1x2a345aa') # {3}匹配 數字3次 print(a.group()) #輸出 345a = re.findall('[0-9]{1,3}','aa1x2a345aa') # {1,3}匹配 數字1-3次 print(a) #輸出 ['1', '2', '345']a = re.findall('abc|ABC','abcdedaABCCDABC') #匹配abc或者ABC print(a) #輸出 ['abc', 'ABC', 'ABC']a = re.findall('(abc){2}','abcabcABCabcdeabcabcdaedabcadedcad') # print(a) #輸出 ['abc', 'abc']a = re.findall('\A[0-9]+[a-z]+\Z','103494abd') #\A 等效于^ \Z 等效于\ print(a) #輸出 ['103494abd']a = re.findall('\D','103494abd\t \n\\') #\D 匹配非數字包括字符和特殊格式 print(a) #輸出 ['a', 'b', 'd', '\t', ' ', '\n', '\\']a = re.findall('\w','103494abd\t \n\\') #\w 匹配數字和字母 print(a) #輸出 ['1', '0', '3', '4', '9', '4', 'a', 'b', 'd']a = re.findall('\W','103494abd\t \n\\') #\W匹配非數字和字母 表示特殊格式與空格 print(a) 輸出 #['\t', ' ', '\n', '\\'] a = re.findall('\s','103494abd\t \n\\') #\s匹配特殊字符 空格 不包括 "\" print(a) #輸出 ['\t', ' ', '\n']a = re.search('(?P<province>[0-9]{2})(?P<city>[0-9]{2})(?P<hometown>[0-9]{2})(?P<birthday>[0-9]{8})', '371481199306143242') print(a.groupdict()) 輸出 #{'province': '37', 'hometown': '81', 'city': '14', 'birthday': '19930614'} a = re.search('[a-z]+','abccdA', flags=re.I) #re.I 忽略大小寫 print(a.group()) #輸出 abccdAa = re.search('[a-z]+','abccdA', flags=re.I) #re.I 忽略大小寫 print(a.group()) 輸出 abccdAa = re.search('[a-z]+d$','abccdA\nsecondline\nthird', flags=re.M) #re.M匹配換行 print(a.group()) #輸出 thirda = re.search('.+','oneline\nsecondline\nthird\nfourthline', flags=re.S) #在.中如何使用re.S可以連換行都能匹配上 print(a.group()) #輸出 oneline secondline third fourthline
?
12、conllections模塊
? 1、Counter函數
counter函數對字符串、列表進行分割,統計字符串出現的次數
import collections obj = collections.Counter('abedjdjajdebaqazwsxedccvfredaa djdjejkd;ddoeeo;ddedpdkdkdk')#元素里出現次數記錄,計數器功能
print(obj) #輸出 Counter({'d': 16, 'e': 8, 'j': 6, 'a': 6, 'k': 4, 'o': 2, 'c': 2, ';': 2, 'b': 2, 'w': 1, 'q': 1, 'v': 1, 'z': 1, ' ': 1, 'f': 1, 'p': 1, 'r': 1, 'x': 1, 's': 1})
ret = obj.most_common(5) #輸出前五個 print(ret) #輸出 [('d', 16), ('e', 8), ('j', 6), ('a', 6), ('k', 4)]
obj = collections.Counter([11,22,33,22,33]) #對列表進行統計 print(obj) #輸出 Counter({33: 2, 22: 2, 11: 1}) obj.update(['erc',11,11,22,11]) #對原有obj進行更新,添加數據 print(obj) #輸出 Counter({11: 4, 22: 3, 33: 2, 'erc': 1}) obj.subtract(['erc', 11,22,33,11]) print(obj) #輸出 Counter({11: 2, 22: 2, 33: 1, 'erc': 0})
?
2、雙向隊列與單向隊列
deque表示雙向隊列,雙向隊列表示從右面與左面均可添加與消耗隊列中的數據
import collections d = collections.deque() d.append('1') #正常的append從右面添加,append可以添加單個元素 d.appendleft('10') #從左面添加 d.appendleft('1') print(d) #輸出 deque(['1', '10', '1']) print(d.count('1')) #輸出 2 d.extend(['aa','bb','aa']) #extend添加多個元素 print(d) #輸出 deque(['1', '10', '1', 'aa', 'bb', 'aa']) d.extendleft(['aa','bb','aa']) print(d) #輸出 deque(['aa', 'bb', 'aa', '1', '10', '1', 'aa', 'bb', 'aa'])
單向隊列只能從一側添加一側消耗
import queue q = queue.Queue() q.put('123') print(q.qsize()) #輸出 1q.put('789') print(q.qsize()) #輸出 2print(q.get()) #輸出 123print(q.get()) #輸出 789
?
? 3、可命名元組
import collectionsM = collections.namedtuple('Mytuple', ['x','y','z']) obj = M(11,22,33) print(obj.x,obj.y,obj.z) #輸出 11 22 33
4、有序字典
?
import collections dic = collections.OrderedDict() #有序字典定義 dic['k1'] = 'v1' dic['k2'] = 'v2' dic['k3'] = 'v3'for i in dic:print(i + '\t\t' + dic[i]) #輸出? k1 v1 k2 v2 k3 v3dic.popitem() print(dic) #輸出 OrderedDict([('k1', 'v1'), ('k2', 'v2')])ret = dic.pop('k1') print(dic) print(ret) #輸出 OrderedDict([('k2', 'v2')]) v1 dic.setdefault('k2','444') #如果沒有就變成444,如果本身有值就不變 dic.setdefault('k4') #只有k4,就把值變為None print(dic) #輸出 OrderedDict([('k2', 'v2'), ('k4', None)])dic.update({'k2': 'v222', 'k10':'v10'}) #通過update方法添加多個元素,如果原來key存在會修改原value print(dic) #輸出 OrderedDict([('k2', 'v222'), ('k4', None), ('k10', 'v10')])
5、默認字典
import collections dic = collections.defaultdict(list) #創建一個字典,字典的默認值為list dic['k1'].append('alex') dic['k1'].extend(['gavin','age',23]) print(dic) #輸出 defaultdict(<class 'list'>, {'k1': ['alex', 'gavin', 'age', 23]})dic1 = collections.defaultdict(dict)dic1['k1']['k1'] = 'v1' dic1['k2']['k2'] = 'v2' print(dic1) #輸出 defaultdict(<class 'dict'>, {'k2': {'k2': 'v2'}, 'k1': {'k1': 'v1'}})
13、subprocess模塊
subprocess將代替os.system與os.spawn模塊,在python2.7中,subprocess模塊調用call()函數顯示實時輸出結果,通過Popen函數保存輸出結果,在python3.5以后,通過run()代替call()函數
import subprocesssubprocess.run('df -h',shell=True)a = subprocess.Popen('df -h',shell=True,stdout=subprocess.PIPE) #run與call和Popen都是如此,如果參數不止一個,同時也不想通過列表方式傳入,需要shell=True #如果需要保存輸出結果,需要通過Popen函數保存,同時需要通過subprocess.PIPE管道方式將結果傳遞給輸出 print(a.stdout.read())
? 終端輸入命令分為兩種:
1、輸入即可得到輸出 ?如ifconfig
2、輸入進行某環境依賴再輸入 如python
需要交互命令實例:
可以使用這個方法與另外一個子進程進行交互(配合管道PIPE來使用)
import subprocess obj = subprocess.Popen(['python'], stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) obj.stdin.write('print 1 \n'.encode('utf-8')) obj.stdin.write('print 2 \n'.encode('utf-8')) obj.stdin.write('print 3 \n'.encode('utf-8')) obj.stdin.write('print 4 \n'.encode('utf-8'))out_err_list = obj.communicate(timeout=10)#如果想結束進程,使用communicate函數 print(out_err_list)
?
14、logging模塊
很多程序都有記錄日志的需求,并且日志中包含的信息既有正常的程序訪問日志,還可能有錯誤告警燈信息輸出,python的logging模塊提供了標準的日志接口,可以通過它存儲各種格式的日志,logging的日志分為debug、info、warning、error5個等級
import logging logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%Y-%m-%d %H:%M:%s ', filename='example-log.log',level=logging.INFO) #%S 表示正常秒 %s表示更精確的秒, %p表示 AM或者PM這個可以和%I一起使用 logging.debug('this message should go to the log files') logging.info('so should this') logging.warning('and this, too')
? 10、二分法
def find_data(data,find_i):if len(data) > 1:if data[int(len(data)/2)] > find_i:print(data[:int(len(data)/2)])find_data(data[:int(len(data)/2)],find_i)elif data[int(len(data)/2)] < find_i:print(data[int(len(data)/2):])find_data(data[int(len(data)/2):],find_i)else:print('find the number: %s' %data[int(len(data)/2)])else:if data[int(len(data)/2)] == find_i:print('find the number: %s' %data[int(len(data)/2)])else:print('cant not find') if __name__ == '__main__':data = list(range(1,50,3))find_data(data,5)
11、冒泡排序
?
data = [10,4,33,21,22,54,3,8,11,5,22,17,13,6] for j in range(1,len(data)):for i in range(len(data)-j):if data[i] > data[i+1]:tmp = data[i]data[i] = data[i+1]data[i+1] = tmpprint(data)
?
12、時間復雜度
時間復雜度是用來衡量算法的優劣,通常來講,算法效率越高,時間復雜度消耗的時間越低,通常來說,時間復雜度分為O(n) 線性復雜度,O(n2)和O(n3),還有 O(1)和O(logn),其中O(1)為常量,不論數據量多大,都是同一時間完成,效率最高,而O(logn)的典型代表就是二分法和二叉樹法,這種方法隨著數據量越高,效率越高, O(n)為線性增長,隨著數據量的增大而線性增大,最后是O(n2) ?O(n3)分別代表算法中存在兩次循環和三次循環,效率比前面的低
?
13、深拷貝
拷貝分為深拷貝與淺拷貝,其中copy.copy()與變量賦值均屬于淺拷貝,淺拷貝的特點為只拷貝第一層數據,而不拷貝第一層以外的數據,這樣的壞處在于修改了第一層以外的數據的拷貝數據時,原始數據也會跟著修改,而深拷貝會拷貝所有數據,無論數據處于第幾層,這樣拷貝數據與原始數據相互之間不受影響
import copy ''' #淺拷貝copy.copy()#深拷貝 copy.deepcopy()#賦值 a = '111' b = a ''' #賦值 a1 = 123 b1 = 123 print(id(a1)) print(id(b1))a2 = a1 print(id(a1)) print(id(a2))#字符串拷貝,對于字符串,深淺拷貝都只是指向內存都一地址 a3 = copy.copy(a1) print(id(a3))a4 = copy.deepcopy(a1) print(id(a4))#對元組/列表/字典拷貝 n1 = {'k1': 'wu', 'k2': 123, 'k3': ['alex',456]} n2 = n1 #賦值 print(id(n1)) print(id(n2))n3 = copy.copy(n1) #淺拷貝,只拷貝一層,所以n3只拷貝了k1 k2 k3對應的值,而k3中代表的列表沒有進行拷貝 print(id(n3))print(id(n3['k3'])) #由于淺拷貝只拷貝一層,所以n3與n1的k3對應的列表內存地址一樣 print(id(n1['k3']))n4 = copy.deepcopy(n1) print(id(n4['k3'])) print(id(n4))
?
?
?
?
?
?
?
?
?
轉載于:https://www.cnblogs.com/xiaopi-python/p/6428082.html
總結
以上是生活随笔為你收集整理的Python学习笔记第五周的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一颗烤瓷牙多少钱啊?
- 下一篇: jQuery_第五章_jQuery事件和