標籤:python進階 十分鐘學會python進階文法
(0)目錄
VMware 下安裝Ubuntu的吐血經曆
零基礎學習Shell編程
Linux下的makefile的妙用
Linux調試神器 -- gdb
十分鐘學會Python的基本類型
分布式版本管理神器--GIT
GIT檔案的三種狀態 & Git SSH秘鑰問題
十分鐘學習Python的進階文法
配置SSH無密碼訪問及Linux熱鍵、重啟、kill進程
Java的不定長參數和Python的不定長參數對比
一:起因
(1)作為膠水語言的Python,可謂無處不在,快速開發原型網站;大資料處理等領域應用甚廣
(2)學過c/c++ 或者 Java的ITers 很容易學習Python,特別是對於上手入門級的Python文法
(3)剛剛開始學習Python,練習Python時,可能感覺特別彆扭 —— 完全沒有方法{} ,近幾年靠:和嚴格的縮排來進行程式碼片段,程式段的分隔
(4)一些Python原始碼的分享,請下載
二:Python 進階語言
(1)python中%r和%s的區別 —— %r用rper()方法處理對象 —— %s用str()方法處理對象
有些情況下,兩者處理的結果是一樣的,比如說處理int型對象:
text = "I am %d years old." % 22 print "I said: %s." % text print "I said: %r." % text I said: I am 22 years old.. I said: 'I am 22 years old.'. // %r 給字串加了單引號
(2)Python中if __name__ == ‘__main__‘:作用
#hello.pydef sayHello(): str="hello" print(str);if __name__ == "__main__": print ('This is main of module "hello.py"') sayHello()
python作為一種指令碼語言,
用python寫的各個module都可以包含以上那麼一個類似c中的main函數,只不過python中的這種__main__與c中有一些區別,主要體現在:
1)當單獨執行該module時,比如單獨執行以上hello.py: python hello.py,則輸出
This is main of module "hello.py"
hello
可以理解為"if __name__=="__main__":" 這一句與c中的main()函數所表述的是一致的,即作為入口;
2)當該module被其它module 引入使用時,其中的"if __name__=="__main__":"所表示的Block不會被執行,這是因為此時module被其它module引用時,其__name__的值將發生變化,__name__的值將會是module的名字。比如在python shell中import hello後,查看hello.__name__:
>>> import hello
>>> hello.__name__
‘hello‘
>>>
3)因此,在python中,當一個module作為整體被執行時,moduel.__name__的值將是"__main__";而當一個module被其它module引用時,module.__name__將是module自己的名字,當然一個module被其它module引用時,其本身並不需要一個可執行檔入口main了
if __name__ == '__main__': print 'This program is being run by itself'else: print 'I am being imported from another module'
(3)我自己的疑問:我能明白物件導向編程的概念,感覺python用模組就能解決,為啥還要有class之類的東西?
1)先回答__:由於python的類成員都是公有、公開的被存取public,缺少像正統物件導向語言的私人private屬性,於是就用__來將就一下,類比私人屬性。這些__屬性往往是內部使用,通常情況下不用改寫。也不用讀取。加上2個底線的目的,一是不和普通公有屬性重名衝突,二是不讓對象的使用者(非開發人員)隨意使用。
2)物件導向是一種方法學的提高,不用對象用模組的確能行,就像C語言也用類似的、沒有對象的方式提供模組,也能開發任何東西。但用了對象能提高代碼複用、提高開發效率,減輕開發人員的勞動。簡單說,物件導向就類似於工廠做一個石膏雕塑:
class類就相當於模具,object對象相當於模具倒出來的雕塑,雕塑可以大量被複製。要修改雕塑,是去修改模具,而不是改雕塑成品。
從資料的角度,一個雕塑可能由多個基礎組件組成,手、腳、頭,這些是資料,當然對象也有動作,對象所有的函數都是它的動作,比如跑、吃、叫。
最常見的,學生類,規定一些資料,姓名、電話、年齡、這些是資料,學生會“答題” “吃飯”,“消費”,“聯絡”“動手”這些是傳遞訊息的動作。
這種把資料和動作結合就是一個對象,類拿來規範這些資料和動作。再次使用這同一類的對象,就不需要重複開發。
(4)Python中__init__(初始化操作) 和 __del__(結束操作,如檔案的關閉和資料庫的關閉等)的作用:
1)Python中沒有專用的構造和解構函式,但是一般可以在__init__和__del__分別完成初始化和刪除操作,可用這個替代構造和析構。還有一個__new__用來定製類的建立過程,不過需要一定的配置,此處不做討論。
2)類的成員函數預設都相當於是public的,但是預設開頭為__的為私人變數,雖然是私人,但是我們還可以通過一定的手段訪問到,即Python不存在真正的私人變數。如:
由於Python的特殊性,全域成員變數是共用的,所以類的執行個體不會為它專門分配內容空間,類似於static,具體使用參看下面的例子。
測試1:# encoding:utf8class NewClass(object): num_count = 0 # 所有的執行個體都共用此變數,即不單獨為每個執行個體分配 def __init__(self,name): self.name = name NewClass.num_count += 1 print name,NewClass.num_count def __del__(self): NewClass.num_count -= 1 print "Del",self.name,NewClass.num_count def test(): print "aa"aa = NewClass("Hello")bb = NewClass("World")cc = NewClass("aaaa")print "Over"Hello 1World 2aaaa 3OverDeException l Hello 2AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF18D0>> ignoredException AttributeError: "'NoneType' object has no attribute 'num_count'" in <bound method NewClass.__del__ of <__main__.NewClass object at 0x01AF1970>> ignored
我們發現,num_count 是全域的,
當每建立一個執行個體,__init__()被調用,num_count 的值增一,當程式結束後,所有的執行個體會被析構,即調用__del__() 但是此時引發了異常。查看異常為 “NoneType” 即 析構時NewClass 已經被記憶體回收,所以會產生這樣的異常。
但是,疑問來了?為什麼會這樣?按照C/C++等語言的經驗,不應該這樣啊!經過尋找資料,發現: Python的記憶體回收過程與常用語言的不一樣,Python按照字典順序進行記憶體回收,而不是按照建立順序進行。所以當系統進行回收資源時,會按照類名A-Za-z的順序,依次進行,我們無法掌控這裡的流程。
SO,繼續尋找,我們還可以通過self.__class__訪問到類本身,然後再訪問自身的共用成員變數,即 self.__class__.num_count , 將類中的NewClass.num_count替換為self.__class__.num_count 編譯運行,如下:
# encoding:utf8class NewClass(object): num_count = 0 # 所有的執行個體都共用此變數,即不單獨為每個執行個體分配 def __init__(self,name): self.name = name self.__class__.num_count += 1 print name,NewClass.num_count def __del__(self): self.__class__.num_count -= 1 print "Del",self.name,self.__class__.num_count def test(): print "aa"aa = NewClass("Hello")bb = NewClass("World")cc = NewClass("aaaa")print "Over"Perfect!我們完美地處理了這個問題!
(5)python中的全域變數和局部變數
函數內部的和函數外部的不共用一個變數,特別是出現 = (等號)時;但是同一個函數內的不同代碼塊之間可以共用一個變數詳見
(6)Python高效讀寫檔案
1)寫入多行 —— file_object.writelines(list_of_text_strings)
注意,調用writelines寫入多行在效能上會比使用write一次性寫入要高。
2)在處理記錄檔的時候,常常會遇到這樣的情況:記錄檔巨大,不可能一次性把整個檔案讀入到記憶體中進行處理,例如需要在一台實體記憶體為 2GB 的機器上處理一個 2GB 的記錄檔,我們可能希望每次只處理其中 200MB 的內容。
在 Python 中,內建的 File 對象直接提供了一個 readlines(sizehint) 函數來完成這樣的事情。以下面的代碼為例:
file = open('test.log', 'r')sizehint = 209715200 # 200Mposition = 0lines = file.readlines(sizehint)while not file.tell() - position < 0:position = file.tell()#Python檔案操作tell()方法:這種方法簡單地返迴文件的當前位置讀/寫指標在檔案。lines = file.readlines(sizehint)
每次調用 readlines(sizehint) 函數,會返回大約 200MB 的資料,而且所返回的必然都是完整的行資料,大多數情況下,返回的資料的位元組數會稍微比 sizehint 指定的值大一點(除最後一次調用 readlines(sizehint) 函數的時候)。通常情況下,Python 會自動將使用者指定的 sizehint 的值調整成內部緩衝大小的整數倍。
(7)Python 的檔案讀取方式
Python提供了基本的函數和必要在預設情況下對檔案進行操作的方法。可以使用一個檔案對象file來做大部分檔案操作。
open 函數:想要讀取或寫入檔案,必須使用Python內建的open()函數來開啟它。該函數建立一個檔案對象,這將用來調用與之關聯的其他支援方式:
文法:file object = open(file_name [, access_mode][, buffering])
1)參數的詳細資料:
file_name: file_name參數是一個字串值,包含您要訪問的檔案的名稱。
access_mode: access_mode決定了檔案必須被開啟,即,讀,寫,追加等的可能值是下表中給定的一個完整的列表的模式。這是選擇性參數,預設檔案存取方式為read (r)。
buffering: 如果緩衝值被設定為0時,沒有緩衝將發生。如果該緩衝值是1,行緩衝會在訪問一個檔案來執行。如果指定的緩衝值為大於1的整數,則緩衝作用將與所指示的緩衝區的大小進行。如果為負,則緩衝區的大小是系統預設(預設行為)。
2)模式 描述
r 開啟一個檔案為唯讀。檔案指標置於該檔案的開頭。這是預設模式。
rb 開啟一個檔案只能以二進位格式讀取。檔案指標置於該檔案的開頭。這是預設模式。
r+ 開啟用於讀取和寫入檔案。檔案指標將會在檔案的開頭。
rb+ 開啟用於讀取和寫入二進位格式的檔案。檔案指標將會在檔案的開頭。
w 開啟一個檔案唯寫。覆蓋該檔案,如果該檔案存在。如果該檔案不存在,則建立用於寫入一個新的檔案。
wb 開啟一個檔案只能以二進位格式寫入。覆蓋該檔案,如果該檔案存在。如果該檔案不存在,則建立用於寫入一個新的檔案。
w+ 開啟用於寫入和讀取的檔案。覆蓋現有的檔案,如果檔案存在。如果該檔案不存在,則建立讀取和寫入新的檔案。
wb+ 開啟用於寫入和讀取的二進位格式的檔案。覆蓋現有的檔案,如果檔案存在。如果該檔案不存在,則建立讀取和寫入新的檔案。
a 將開啟追加檔案。檔案指標是在檔案的結尾。也就是說,該檔案是在附加模式。如果該檔案不存在,它創造了寫入一個新的檔案。
ab 將開啟追加的二進位格式的檔案。檔案指標在該檔案的結束。也就是說,該檔案為追加模式。如果該檔案不存在,它建立並寫入一個新的檔案。
a+ 開啟為追加和讀取檔案。檔案指標在該檔案的結束。該檔案將為追加模式。如果該檔案不存在,它建立並讀取和寫入的新檔案。
ab+ 開啟兩個追加和讀取的二進位格式的檔案。檔案指標在該檔案的結束。該檔案將在追加模式。如果該檔案不存在,它建立並讀取和寫入的新檔案。
3)檔案操作:
os.mknod("test.txt") 建立空檔案
fp = open("test.txt","w+") 直接開啟一個檔案,如果檔案不存在則建立檔案
fp.read([size]) #size為讀取的長度,以byte為單位
fp.readline([size]) #讀一行,如果定義了size,有可能返回的只是一行的一部分
fp.readlines([size]) #把檔案每一行作為一個list的一個成員,並返回這個list。其實它的內部是通過迴圈調用readline()來實現的。如果提供size參數,size是表示讀取內容的總長,也就是說可能唯讀到檔案的一部分。
fp.write(str) #把str寫到檔案中,write()並不會在str後加上一個分行符號
fp.writelines(seq) #把seq的內容全部寫到檔案中(多行一次性寫入)。這個函數也只是忠實地寫入,不會在每行後面加上任何東西。
fp.close() #關閉檔案。python會在一個檔案不用後自動關閉檔案,不過這一功能沒有保證,最好還是養成自己關閉的習慣。 如果一個檔案在關閉後還對其進行操作會產生ValueError
fp.flush() #把緩衝區的內容寫入硬碟
fp.fileno() #返回一個長整型的”檔案標籤“
fp.isatty() #檔案是否是一個終端裝置檔案(unix系統中的)
fp.tell() #返迴文件操作標記的當前位置,以檔案的開頭為原點
fp.next() #返回下一行,並將檔案操作標記位移到下一行。把一個file用於for … in file這樣的語句時,就是調用next()函數來實現遍曆的。
fp.seek(offset[,whence]) #將檔案打操作標記移到offset的位置。這個offset一般是相對於檔案的開頭來計算的,一般為正數。但如果提供了whence參數就不一定了,whence可以為0表示從頭開始計算,1表示以當前位置為原點計算。2表示以檔案末尾為原點進行計算。需要注意,如果檔案以a或a+的模式開啟,每次進行寫操作時,檔案操作標記會自動返回到檔案末尾。
fp.truncate([size]) #把檔案裁成規定的大小,預設的是裁到當前檔案操作標記的位置。如果size比檔案的大小還要大,依據系統的不同可能是不改變檔案,也可能是用0把檔案補到相應的大小,也可能是以一些隨機的內容加上去。
(8)目錄操作:
os.mkdir("file") 建立目錄
複製檔案:
shutil.copyfile("oldfile","newfile") oldfile和newfile都只能是檔案
shutil.copy("oldfile","newfile") oldfile只能是檔案夾,newfile可以是檔案,也可以是目標目錄
複製檔案夾:
shutil.copytree("olddir","newdir") olddir和newdir都只能是目錄,且newdir必須不存在
重新命名檔案(目錄)
os.rename("oldname","newname") 檔案或目錄都是使用這條命令
移動檔案(目錄)
shutil.move("oldpos","newpos")
刪除檔案
os.remove("file")
刪除目錄
os.rmdir("dir")只能刪除空目錄
shutil.rmtree("dir") 空目錄、有內容的目錄都可以刪
轉換目錄
os.chdir("path") 換路徑
2)將檔案夾下所有圖片名稱加上‘_fc‘
python代碼:
# -*- coding:utf-8 -*-import reimport osimport time#str.split(string)分割字串#'串連符'.join(list) 將列表組成字串def change_name(path): global i if not os.path.isdir(path) and not os.path.isfile(path): return False if os.path.isfile(path): file_path = os.path.split(path) #分割出目錄與檔案 lists = file_path[1].split('.') #分割出檔案與副檔名 file_ext = lists[-1] #取出尾碼名(列表切片操作) img_ext = ['bmp','jpeg','gif','psd','png','jpg'] if file_ext in img_ext: os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext) i+=1 #注意這裡的i是一個陷阱 #或者 #img_ext = 'bmp|jpeg|gif|psd|png|jpg' #if file_ext in img_ext: # print('ok---'+file_ext) elif os.path.isdir(path): for x in os.listdir(path): change_name(os.path.join(path,x)) #os.path.join()在路徑處理上很有用
十分鐘學習Python的進階文法