python之路第三篇
python文件目錄操作 |
python中對文件、文件夾(文件操作函數)的操作需要涉及到os模塊和shutil模塊。
得到當前工作目錄,即當前Python腳本工作的目錄路徑: os.getcwd()
返回指定目錄下的所有文件和目錄名:os.listdir()
函數用來刪除一個文件:os.remove()
刪除多個目錄:os.removedirs(r“c:\python”)
檢驗給出的路徑是否是一個文件:os.path.isfile()
檢驗給出的路徑是否是一個目錄:os.path.isdir()
判斷是否是絕對路徑:os.path.isabs()
檢驗給出的路徑是否真地存:os.path.exists()
返回一個路徑的目錄名和文件名:os.path.split() eg os.path.split(‘/home/swaroop/byte/code/poem.txt‘) 結果:(‘/home/swaroop/byte/code‘, ‘poem.txt‘)
分離擴展名:os.path.splitext()
獲取路徑名:os.path.dirname()
獲取文件名:os.path.basename()
運行shell命令: os.system()
讀取和設置環境變量:os.getenv() 與os.putenv()
給出當前平臺使用的行終止符:os.linesep
指示你正在使用的平臺:os.name 對於Windows,它是‘nt‘,而對於Linux/Unix用戶,它是‘posix‘
重命名:os.rename(old, new)
創建多級目錄:os.makedirs(r“c:\python\test”)
創建單個目錄:os.mkdir(“test”)
獲取文件屬性:os.stat(file)
修改文件權限與時間戳:os.chmod(file)
終止當前進程:os.exit()
獲取文件大小:os.path.getsize(filename)
文件操作 |
os.mknod("test.txt") 創建空文件
fp = open("test.txt",w) 直接打開一個文件,如果文件不存在則創建文件
關於open 模式:
w 以寫方式打開,
a 以追加模式打開 (從 EOF 開始, 必要時創建新文件)
r+ 以讀寫模式打開
w+ 以讀寫模式打開 (參見 w )
a+ 以讀寫模式打開 (參見 a )
rb 以二進制讀模式打開
wb 以二進制寫模式打開 (參見 w )
ab 以二進制追加模式打開 (參見 a )
rb+ 以二進制讀寫模式打開 (參見 r+ )
wb+ 以二進制讀寫模式打開 (參見 w+ )
ab+ 以二進制讀寫模式打開 (參見 a+ )
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把文件補到相應的大小,也可能是以一些隨機的內容加上去。
目錄操作 |
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") 換路徑
python編碼和轉碼 |
字符編碼的歷史
第一階段:起源,ASCII
計算機是美國人發明的,人家用的是美式英語,字符比較少,所以一開始就設計了一個不大的二維表,128個字符,取名叫ASCII(American Standard Code for Information Interchange)。但是7位編碼的字符集只能支持128個字符,為了表示更多的歐洲常用字符對ASCII進行了擴展,ASCII擴展字符集使用8位(bits)表示一個字符,共256字符。即其最多只能用 8 位來表示(一個字節)。
第二階段:GBK
當計算機傳到了亞洲,尤其是東亞,國際標準被秒殺了,路邊小孩隨便說句話,256個碼位就不夠用了。於是,中國定制了GBK。用2個字節代表一個字符(漢字)。其他國家也紛紛定制了自己的編碼,例如:
日本把日文編到Shift_JIS
裏,韓國把韓文編到Euc-kr
裏。
第三階段:unicode
當互聯網席卷了全球,地域限制被打破了,不同國家和地區的計算機在交換數據的過程中,就會出現亂碼的問題,跟語言上的地理隔離差不多。為了解決這個問題,一個偉大的創想產生了——Unicode(萬國碼)。Unicode編碼系統為表達任意語言的任意字符而設計。
規定所有的字符和符號最少由 16 位來表示(2個字節),即:2 **16 = 65536,註:此處說的的是至少2個字節(16位),可能更多。
第四階段:UTF-8
unicode的編碼方式雖然包容萬國,但是對於英文等字符就會浪費太多存儲空間。於是出現了UTF-8,是對Unicode編碼的壓縮和優化,遵循能用最少的表示就用最少的表示,他不再使用最少使用2個字節,而是將所有的字符和符號進行分類:ascii碼中的內容用1個字節保存、歐洲的字符用2個字節保存,東亞的字符用3個字節保存。
unicode:包容萬國,優點是字符->數字的轉換速度快,缺點是占用空間大
utf-8:精準,對不同的字符用不同的長度表示,優點是節省空間,缺點是:字符->數字的轉換速度慢,因為每次都需要計算出字符需要多長的Bytes才能夠準確表示
內存中使用的編碼是unicode,用空間換時間,為了快 因為程序都需要加載到內存才能運行,因而內存應該是盡可能的保證快。 硬盤中或者網絡傳輸用utf-8,網絡I/O延遲或磁盤I/O延遲要遠大與utf-8的轉換延遲,而且I/O應該是盡可能地節省帶寬,保證數據傳輸的穩定性。 因為數據的傳輸,追求的是穩定,高效,數據量越小數據傳輸就越靠譜,於是都轉成utf-8格式的,而不是unicode。
字符編碼的使用:
1)文本編輯器存取文件的原理(nodepad++,pycharm,word)
打開編輯器就打開了啟動了一個進程,是在內存中的,所以在編輯器編寫的內容也都是存放與內存中的,斷電後數據丟失。因而需要保存到硬盤上,點擊保存按鈕,就從內存中把數據刷到了硬盤上。在這一點上,我們編寫一個py文件(沒有執行),跟編寫其他文件沒有任何區別,都只是在編寫一堆字符而已。
無論是何種編輯器,要防止文件出現亂碼,核心法則就是,文件以什麽編碼保存的,就以什麽編碼方式打開。
2)python解釋器執行py文件的原理 (python test.py)
第一階段:python解釋器啟動,此時就相當於啟動了一個文本編輯器
第二階段:python解釋器相當於文本編輯器,去打開test.py文件,從硬盤上將test.py的文件內容讀入到內存中
第三階段:python解釋器解釋執行剛剛加載到內存中test.py的代碼
補充:
所以,在寫代碼時,為了不出現亂碼,推薦使用UTF-8,會加入 # -*- coding: utf-8 -*-
即
#!/usr/bin/env python # -*- coding: utf-8 -*- print "你好,世界"
python解釋器會讀取test.py的第二行內容,# -*- coding: utf-8 -*-,來決定以什麽編碼格式來讀入內存,這一行就是來設定python解釋器這個軟件的編碼使用的編碼格式這個編碼。
如果不在python文件指定頭信息#-*-coding:utf-8-*-,那就使用默認的python2中默認使用ascii,python3中默認使用utf-8
總結:
1)python解釋器是解釋執行文件內容的,因而python解釋器具備讀py文件的功能,這一點與文本編輯器一樣
2)與文本編輯器不一樣的地方在於,python解釋器不僅可以讀文件內容,還可以執行文件內容
3)python2和python3的一些不同
1) python2中默認使用ascii,python3中默認使用utf-8
2) Python2中,str就是編碼後的結果bytes,str=bytes,所以s只能decode。
3) python3中的字符串與python2中的u‘字符串‘,都是unicode,只能encode,所以無論如何打印都不會亂碼,因為可以理解為從內存打印到內存,即內存->內存,unicode->unicode
4) python3中,str是unicode,當程序執行時,無需加u,str也會被以unicode形式保存新的內存空間中,str可以直接encode成任意編碼格式,s.encode(‘utf-8‘),s.encode(‘gbk‘)
#unicode(str)-----encode---->utf-8(bytes) #utf-8(bytes)-----decode---->unicode
5)在windows終端編碼為gbk,linux是UTF-8.
python函數 |
遞歸 |
1 def calc(n): 2 print(n) 3 if int(n/2)>0: 4 return calc(int(n/2)) 5 print(n) 6 7 n=calc(10)
運行結果:
1 執行結果: 2 10 3 5 4 2 5 1 6 1
函數的好處
1.沒有使用函數導致代碼結構無組織無結構,代碼冗余;
2.沒有使用函數導致代碼可讀性差
3.沒有使用函數導致代碼無法統一管理且維護成本高
函數的分類:
在python中函數分兩類:內置函數,自定義函數
1、內置函數
內置函數1 sum 2 max 3 min 4 5 a=len(‘hello‘) 6 print(a) 7 8 b=max([1,2,3]) 9 print(b)
2、自定義函數
def print_star(): print(‘#‘*6) def print_msg(): print(‘hello world‘) print_star() print_star() print_star() print_msg() print_star() print_star() print_star()
3、函數參數
從大的角度去看,函數的參數分兩種:形參(變量名),實參(值)
#1)定義階段 def foo(x,y): #x=1,y=2 print(x) print(y) #2)調用階段 foo(1,2)
詳細的區分函數的參數分為五種:
位置參數,關鍵字參數,默認參數,可變長參數(*args,**kwargs),命名關鍵字參數
1)位置參數:
1 def foo(x,y,z):#位置形參:必須被傳值的參數 2 print(x,y,z) 3 4 foo(1,2,3) 5 foo(1,2,3) #位置實參數:與形參一一對應
2)關鍵字參數:key = value
def foo(x,y,z): print(x,y,z) foo(z=3,x=1,y=2) # 關鍵字參數需要註意的問題: # 1:關鍵字實參必須在位置實參後面 # 2: 不能多次重復對一個形參數傳值 foo(1,z=3,y=2) #正確 foo(x=1,2,z=3) #錯誤 foo(1,x=1,y=2,z=3)
3)默認參數:
def register(name,age,sex=‘male‘): #形參:默認參數 print(name,age,sex) register(‘asb‘,age=40) register(‘a1sb‘,39) register(‘a2sb‘,30) register(‘a3sb‘,29) register(‘鋼蛋‘,20,‘female‘) register(‘鋼蛋‘,sex=‘female‘,age=19)
默認參數需要註意的問題:
一:默認參數必須跟在非默認參數後
def register(sex=‘male‘,name,age): #在定義階段就會報錯
print(name,age,sex)
(了解)二:默認參數在定義階段就已經賦值了,而且只在定義階段賦值一次
a=100000000
def foo(x,y=a):
print(x,y)
a=0
foo(1)
三:默認參數的值通常定義成不可變類型
4)可變長參數(*args,**kwargs)
1 def foo(x,y,*args): #*會把溢出的按位置定義的實參都接收,以元組的形式賦值給args 2 print(x,y) 3 print(args) 4 5 foo(1,2,3,4,5) 6 7 8 def add(*args): 9 res=0 10 for i in args: 11 res+=i 12 return res 13 print(add(1,2,3,4)) 14 print(add(1,2)) 15 16 def foo(x, y, **kwargs): # **會把溢出的按關鍵字定義的實參都接收,以字典的形式賦值給kwargs 17 print(x, y) 18 print(kwargs) 19 foo(1,2,a=1,name=‘egon‘,age=18) 20 21 22 def foo(name,age,**kwargs): 23 print(name,age) 24 if ‘sex‘ in kwargs: 25 print(kwargs[‘sex‘]) 26 if ‘height‘ in kwargs: 27 print(kwargs[‘height‘]) 28 29 foo(‘egon‘,18,sex=‘male‘,height=‘185‘) 30 foo(‘egon‘,18,sex=‘male‘)
5)命名關鍵字參數(了解)
1 def foo(name,age,*,sex=‘male‘,height): 2 print(name,age) 3 print(sex) 4 print(height) 5 #*後定義的參數為命名關鍵字參數,這類參數,必須被傳值,而且必須以關鍵字實參的形式去傳值 6 foo(‘egon‘,17,height=‘185‘) 7 8 9 10 def foo(name,age=10,*args,sex=‘male‘,height,**kwargs): 11 def foo(name,age=10,*args,sex=‘male‘,height,**kwargs): 12 print(name) 13 print(age) 14 print(args) 15 print(sex) 16 print(height) 17 print(kwargs) 18 19 foo(‘alex‘,1,2,3,4,5,sex=‘female‘,height=‘150‘,a=1,b=2,c=3) 20 21 22 def foo(*args): 23 print(args) 24 25 foo(1,2,3,4) # 1,2,3,4 <=====>*(1,2,3,4) 26 27 *[‘A‘,‘B‘,‘C‘,‘D‘],=====>‘A‘,‘B‘,‘C‘,‘D‘ 28 foo(*[‘A‘,‘B‘,‘C‘,‘D‘]) #foo(‘A‘,‘B‘,‘C‘,‘D‘) 29 foo([‘A‘,‘B‘,‘C‘,‘D‘]) # 30 31 def foo(x,y,z): 32 print(x,y,z) 33 34 # foo(*[1,2,3]) #foo(1,2,3) 35 foo(*[1,2]) #foo(1,2) 36 37 38 def foo(**kwargs): 39 print(kwargs) 40 41 #x=1,y=2 <====>**{‘y‘: 2, ‘x‘: 1} 42 # foo(x=1,y=2) 43 44 foo(**{‘y‘: 2, ‘x‘: 1,‘a‘:1}) #foo(a=1,y=2,x=1) 45 46 def foo(x,y,z): 47 print(x,y,z) 48 49 # foo(**{‘z‘:3,‘x‘:1,‘y‘:2}) #foo(x=1,z=3,y=2) 50 foo(**{‘z‘:3,‘x‘:1}) #foo(x=1,z=3) 51 52 53 def foo(x,y,z): 54 print(‘from foo‘,x,y,z) 55 56 def wrapper(*args,**kwargs): 57 print(args) 58 print(kwargs) 59 60 61 wrapper(1,2,3,a=1,b=2) 62 63 64 65 def foo(x,y,z): 66 print(‘from foo‘,x,y,z) 67 def wrapper(*args,**kwargs): 68 print(args) #args=(1,2,3) 69 print(kwargs) #kwargs={‘a‘:1,‘b‘:2} 70 foo(*args,**kwargs) #foo(*(1,2,3),**{‘a‘:1,‘b‘:2}) #foo(1,2,3,b=2,a=1) 71 # wrapper(1,2,3,a=1,b=2) 72 wrapper(1,z=2,y=3) 73 74 75 76 def foo(x,y,z): 77 print(‘from foo‘,x,y,z) 78 def wrapper(*args,**kwargs): 79 # print(args) #args=(1,) 80 # print(kwargs) #kwargs={‘y‘:3,‘z‘:2} 81 foo(*args,**kwargs) #foo(*(1,),**{‘y‘:3,‘z‘:2}) #foo(1,z=2,y=3) 82 # wrapper(1,2,3,a=1,b=2) 83 wrapper(1,z=2,y=3)
python之路第三篇