python基础之文件操作,集合,函数
文件操作: ??
打開文件的方法:
?
第一種:打開文件執行完命令后,需要關閉文件,否則會一直占用內存空間
f=open('/data/1.txt','r+') ? ?#后面的r+ 表示打開文件的模式是讀寫
#命令?
f.close ? ? #關閉文件?
?
第二種:這種會自動關閉文件,不用我們手動關閉,這種寫法被稱為python中的語法糖。
with open('/data/1.txt','r+') as f:
? ? #命令 ?
?
##################
打開文件的模式:
r : 只讀模式,默認如果不加模式就是只讀模式 ??
r+: 讀寫模式,讀,寫,追加,如果文件不存在會報錯。 ??
w:只寫模式 ?,會覆蓋文件內容,如果文件不存在會創建
w+: 寫讀模式 ,會覆蓋文件內容,如果文件不存在會創建
a:追加模式 ?,如果文件不存在會創建
a+:和a的意思一樣 ? ??
b :二進制(字節)模式處理文件。 當需要處理二進制文件時,需要加一個b,比如rb,wb,ab, 需要注意的是b的方式在打開或寫入時不能指定編碼格式,只能打開后加.decode('utf-8')進行解碼, ?用wb方式寫入時需要將字符串轉化為字節
?
###########################################################
?
小例子:編碼錯誤
#!/usr/bin/env python # encoding:utf-8 f = open('歌詞','r') data = f.read() f.close()print(data) #執行結果: UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 22: illegal multibyte sequence #分析 當時編輯 '歌詞' 這個文件時,我的編輯器的編碼是utf-8 , 所以 '歌詞' 這個文件編碼就是utf-8, 現在用open()函數打開,open()函數會去找系統的默認編碼,windows的系統一般是gbk編碼格式的,所以會報錯,而mac默認編碼就是utf-8,打開就不會報錯了,這里的解決辦法是在打開文件時,指定編碼格式# 指定編碼格式 f = open('歌詞','r',encoding='utf-8') data = f.read() f.close()print(data)?
小例子: 二進制模式讀取文件
#錯誤示例: f = open('666.txt','rb',encoding='utf-8') data = f.read() f.close() print(data) #執行結果 ValueError: binary mode doesn't take an encoding argument # 二進制模式處理文件時,不能用encoding 指定編碼 #正確示例: f = open('666.txt','rb') data = f.read() f.close() print(data) #執行結果: b'66666\r\n2312313' # 注意windows 中的換行符是 \r\n 而linux中是\n 開頭的b表示字節#特別注意:當666.txt 這個文件里有中文,這個時候print (data) 會出現 xe4\xb8 這種16進制的,無法看到中文,這個時候需要用.decode()解碼,print(data.decode())
?
小例子:二進制模式寫文件
#錯誤示例 txt1=''' 又一年花如繡,山中雪埋紅豆。 曾是誰把盞問,可飲一杯否。 ''' f=open(txt1.log,'wb') f.write(txt1) f.close()#執行結果 TypeError: a bytes-like object is required, not 'str' #字符串不能用b寫入,必須轉化成字節 #正確示例 f=open('txt1.log','wb') f.write(txt1.encode(encoding='utf-8')) f.close()#分析:因為用b寫文件必須轉成字節格式,所以用encode()編碼,encode()里面可以指定編碼格式,我這里是utf8,特別注意,前面說過b模式不能指定編碼格式,說的是用open()函數打開的時候不能指定,我在打開后指定的
#bytes() 函數也可以轉換成字節,bytes(txt1,encoding='utf-8') ?
?
#字符串 ?---------- encode() -----------> 字節 ? ,編碼過程?
#字節 ? ---------- decode() -----------> 字符串 ? ,解碼過程?
?
?
下面來看用with處理文件的小例子: ?
txt1=''' 又一年花如繡,山中雪埋紅豆。 曾是誰把盞問,可飲一杯否。 '''with open('123.txt','a') as f:f.write(txt1)with open('123.txt','r') as f:a=f.read()with open('123.txt','r') as f:b=f.read(9)print(a) print(b) #執行結果: 又一年花如繡,山中雪埋紅豆。 曾是誰把盞問,可飲一杯否。又一年花如繡,山上面這段代碼會把txt1中的內容追加到123.txt這個文件中。 ?然后用read()讀出全部賦值給a并打印出來,也可以指定讀取的字符長度,賦值給b打印出來。但是:如果文件大的話不要用read()這種方法,可能不能全部讀出來
特別注意:文件操作中除了read()方法?是讀取的字符,其他方法都是讀取的字節,在utf-8編碼中,一個漢字占3個字節
?
除了用read讀之外還好有其他方式,下面來介紹:
with open('123.txt','r') as f:line1=f.readline()print (line1)line1的結果:?又一年花如繡,山中雪埋紅豆。
說明readline()只讀了一行。 如果要讀全部內容那就用循環去一行一行的讀唄,如下方法:
with open('123.txt','r') as f:while True:line1=f.readline()if len(line1) == 0:breakprint (line1)readline()用這種循環的方法就把全部內容都讀了出來!
? ?
?
with open('123.txt','r') as f:line2=f.readlines()print (line2)line2的結果:['又一年花如繡,山中雪埋紅豆。\n', '曾是誰把盞問,可飲一杯否。\n']
說明readlines() 全讀出來了,但讀出來的是一個列表。 ?當文件很大的時候不建議用這種 ,可能會出現卡住的情況
? ?
?
小例子:write寫文件的時候只能寫字符串 ?,?writelines 可以寫列表,但是列表中的元素必須是字符串
f = open('1.txt','w',encoding='utf-8') #用write寫的時候只能寫字符串 f.write('11111111111\n') #如果不加換行符,會寫在一行里 f.write('2222222222222\n') #用writelines 可以寫列表,但是列表中的元素必須是字符串 f.writelines(['1\n','2\n']) f.close()?
?獲取真正的換行符
# 前面的例子說過,二進制模式rb讀取文件時,可以看到windows系統的換行符是 \r\n # 假如不用二進制模式打開,用默認的文本模式打開看到換行符不是 \r\n f = open('1.txt','r') data = f.readlines() f.close() print(data) #執行結果: ['11111111111\n', '2222222222222\n', '1\n', '2\n'] # 分析,因為python 會處理來自不同系統的文件,所以python內部做了轉換,統一把換行符轉成 \n ,如果要顯示真實的換行符 可以在打開文件時加 newline='' f = open('1.txt','r',newline='') data = f.readlines() f.close() print(data) # 執行結果: ['11111111111\r\n', '2222222222222\r\n', '1\r\n', '2\r\n']?
?
文件游標 ? ?
with open('333.txt','w') as f:f.write(txt3) with open('333.txt','r') as f:print(f.tell())print (f.readline().strip()) #strip表示去掉換行符和空格print(f.readline().strip())print(f.tell())f.seek(0)print(f.readline().strip()) #執行結果: 0 121212121233 qwertyu 23 121212121233?說明:tell() 方法會顯示當前的指針(游標)位置,第一次肯定是0,然后讀了兩行,那指針位置就是在兩行之后,然后用seek(0)方法把指針位置調整到0,seek()方法控制指針的位置。再次讀取一行,還是讀取的第一行,因為指針在哪,就從哪里開始讀。 ??
?
?seek()方法的高級用法
seek() 方法的作用就是控制指針的位置seek() 方法其實有三種模式,分別是 0 , 1 , 2 我下面會舉例說明第一種 0模式,從頭開始(默認的模式)text = '''123333456789 qwertyuio 我是好人 666'''f = open('seek.log','w',encoding='utf-8') f.write(text) f.close()f = open('seek.log','r',encoding='utf-8') print(f.tell()) f.seek(5) print(f.tell()) f.seek(6,0) print(f.tell()) print(f.read()) f.close() #執行結果: 0 5 6 456789 qwertyuio 我是好人 666 #分析: 第一個f.tell() 肯定是0, 因為文件開頭指針肯定是0, 然后f.seek(5)把指針從開頭往后移動了5個字節, 那現在的f.tell()就是5, 然后又f.seek(6,0)從頭開始移動6個字節, 現在的f.tell() 指針位置就是6, 最后f.read()的結果就是把指針后面的全部讀取, 指針在6, 所以把第6個字節后面的全部讀取 #這種模式就是0模式, 可以寫成 f.seek(5,0), 因為0可以省略, 一般就寫 f.seek(5) 就行了 第二種, 1模式,相對路徑f = open('seek.log','rb') print(f.tell()) f.seek(5) print(f.tell()) f.seek(6,1) print(f.tell()) print(f.read().decode()) f.close()#執行結果: 0 5 11 9 qwertyuio 我是好人 666 #分析: 第一個f.tell() 肯定是0, 因為文件開頭指針肯定是0, 然后f.seek(5)這是第一個seek(), 把指針從開頭往后移動了5個字節, 那現在的f.tell()就是5, 然后又f.seek(6,1)從當前指針的位置, 也就是第5個字節的位置又移動6個字節, 現在的f.tell() 指針位置就是11, 最后f.read()的結果就是把指針后面的全部讀取, 指針在11, 所以把第11個字節后面的全部讀取 #特別注意,因為seek()操作的是字節,字節既是二進制模式,除了默認的0模式可以不用b打開,其他兩種模式都得用b打開 第三種, 2模式, 倒序 f = open('seek.log','rb') f.seek(-10,2) print(f.tell()) print(f.read().decode()) f.close() # 執行結果: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa5 in position 0: invalid start byte #分析: 因為倒數第10個字節在 好 字上,一個漢字占3個字節,好 恰好占了倒數 9,倒數10, 倒數11這三個字節, 不能把漢字拆開,所以報錯 f = open('seek.log','rb') f.seek(-11,2) print(f.tell()) print(f.read().decode()) f.close() #執行結果: 31 好人 666 #分析:倒數第11個字節, 也就是從頭開始的指針是31, 把倒數第11個字節后的或者說是正序第31個字節后的全部讀取, 需要注意換行符是 \r\n 占了兩個字節 #特別注意,因為seek()操作的是字節,字節既是二進制模式,除了默認的0模式可以不用b打開,其他兩種模式都得用b打開
?
?
文件截取 ?truncate() ? ?
text = ''' 我們是共產主義接班人 ''' with open('test.log','w') as f:f.write(text)with open('test.log','r+') as f:f.truncate(6) #查看test.log,發現文件內容是 我們 #分析,在utf-8的編碼中一個漢字占3個字節,除了read()是字符,其他方法都是字節。 # 注意:文件截取 truncate(6) 必須是可寫的模式打開,但不能是w,因為w直接重新創建文件了,可以是 r+ 或者 a+?
再來看文件操作的最后一個例子: ??
txt2='''請欣賞一首現代詩 黑夜給了我黑色的眼睛 我卻用它尋找光明 '''with open('new.txt','w') as f:f.write(txt2)with open('new.txt','r') as f:first_line=f.readline() #讀取第一行內容,指針會移動到第一行的后面,再讀的時候就會去第一行后面開始讀print('first_line:',first_line)print('分割線'.center(50,'-')) #表示以'分割線'為中心,用-補齊50個長度data=f.read() #讀取剩下的內容,print (data) # 執行結果: first_line: 請欣賞一首現代詩-----------------------分割線------------------------ 黑夜給了我黑色的眼睛 我卻用它尋找光明?
##########################
其他常用文件操作:
?f.name ? #打印文件名字 ?
f.flush() ? #把文件內容從內存刷到硬盤 ??
f.closed ? #文件如果關閉則返回True ??
f.encoding ? #查看使用open()打開文件的編碼, 二進制模式的沒有此方法
############################ ??
集合:?
集合是一個無序的,不重復的數據類型。
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1) #集合會去重print (list1,type(list1))結果是:{1, 2, 3, 4, 5, 6, 7, 8, 9} <class 'set'> ??
結果看上去像排序了的,其實是無序的,數據多了就會看出是無序的。有點像字典,但類型是集合。 ??
?
?
集合的方法:
1,增加
list1.add('a') ?#增加一個元素,可以重復添加相同的值,但是沒用,集合去重的
list1.update(['b','c','d']) ?#?增加多個元素
?
2, 刪除元素?
list1.remove('a') ?#刪除元素a,直接寫要刪除的元素名稱就可以 ,但元素不存在時報錯 ?
list1.discard('a') ?#刪除元素a,直接寫要刪除的元素名稱就可以 ,元素不存在時不報錯?
list1.pop() ? #隨機刪除一個元素,因為集合是無序的
?
3,判斷成員身份
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1)print (2 in list1) #正確就返回True print (2 not in list1) #正確就返回True?
?
?
并集 ??
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1)list2=[1,'a',5,'b',9] list2=set(list2)#方法一: list3=list1|list2 print (list3)#方法二: list3=list1.union(list2) print (list3)返回結果:?{1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b'} ?把兩個集合的所有元素合并,然后去掉重復的
?
?
交集 ? ?
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1)list2=[1,'a',5,'b',9] list2=set(list2)#方法一: list3=list1 & list2 print (list3)#方法二: list3=list1.intersection(list2) print (list3)返回結果:{1, 5, 9} ?把兩個集合的公共的部分取出來 ? ?
?
?
差集?
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1)list2=[1,'a',5,'b',9] list2=set(list2)#方法一: list3=list1 - list2 print (list3)#方法二: list3=list1.difference(list2) #求list1對list2的差集,就是把list1有的,但list2沒有的取出來 print (list3)返回結果:{2, 3, 4, 6, 7, 8}?求list1對list2的差集,就是把list1有的,但list2沒有的取出來 ? ?
?
?
子集與父集?
list1=[1,2,3,4,5,6,7,7,7,8,9] list1=set(list1)list2=[1,5,9] list2=set(list2)print (list2.issubset(list1)) #判斷list2是否是list1的子集,也就是說list2的元素是否list1都有,如果是就返回True print (list1.issuperset(list2)) #判斷list1是否是list2的父集,也就是說list2的元素是否list1都有,如果是就返回True?
?
############################### ? ?
?
函數 ?
函數的作用:
1,減少代碼重復性?
2,使程序變得可擴展
3,使程序變得易維護 ?
?
定義函數
1,
def func1(): #用def這個關鍵字去定義函數,func1 是函數名print ("hello,world") #函數里面的內容func1() #用函數名加括號的方式去調用這個函數? ??
2,
def func1():print ("this is func1")return 0 #返回一個0,注意return代表函數結束,即使后面還有命令也不會執行。def func2():print ("this is func2")return 1,"哈哈",[1,2,3],{1:'a'} #看上去返回一堆東西,把return賦值給一個變量后,實際上打印出來的是一個元組,用元組包了起來def func3(a,b): #這個函數有參數,叫做形參res=a**b return res #返回res的值x=func1() #執行func1函數并把return的返回值賦值給x,如果沒有return,返回的是None y=func2() #執行func2函數并把return的返回值賦值給y,如果沒有return,返回的是None z=func3(2,3) #執行func3(a,b)函數,并把2傳遞給a,把3傳遞給b,執行完命令后把結果res賦值給z,剛才說的a和b叫形參,那么2和3叫實參,就是實際傳遞的參數print (x) print (y) print (z)?
3,默認參數 ??
def stu(name,age,country='china'): #設置country這個參數的值是默認的,有默認參數必須放在最后print ("your name is %s" %name)print ("your age is %s" %age)print ("your country is %s" %country)stu("zhang",18)#執行函數時如果不指定第三個參數,那第三個參數就用默認的,如果指定了,那就按照你指定的傳參,實參也可以指定固定的,比如stu("zhang",agr=19) 同樣,指定的實參也必須放在后面。
#正常情況,給函數傳參要按照順序來的,不按順序會出錯,比如stu("zhang",name="li") 這樣會出錯,因為zhang已經傳遞給形參name了,再給name傳遞一個肯定不行了。
?
4,非固定參數(如果不確定用戶要傳入多少參數,就用非固定參數)
def stu(name,age,*args): # args 把用戶傳入的參數形成一個元組的形式print ("your name is %s" %name)print ("your age is %s" %age)print (args)stu("zhang",18,'china','you are a good man') 返回結果: your name is zhang your age is 18 ('china', 'you are a good man')如果傳入的值是類似這種的sex="male",那 *args 就不能處理了,這就用到了 **kwargs ??
def stu(name,age,**kwargs): #kwargs 會把用戶傳遞的參數形成字典形式print ("your name is %s" %name)print ("your age is %s" %age)print (kwargs)stu("zhang",18,sex="male",country='china') 返回的結果: your name is zhang your age is 18 {'country': 'china', 'sex': 'male'}?
?
?
?
轉載于:https://www.cnblogs.com/nianqingguo/p/5754212.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的python基础之文件操作,集合,函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DoraCMS 源码知识点备注
- 下一篇: Python+Selenium WebD