Python 基礎三 檔案 函數,
今天回顧一下之前學的檔案操作相關知識點,對於檔案的操作,主要有一下幾部分構成:
一、檔案的基礎知識
1.檔案操作的基本流程
檔案操作其實可以分成三大部分:
1.開啟檔案,擷取檔案控制代碼並賦予一個變數
2.通過控制代碼對檔案進行讀與寫的操作
3.操縱完畢後,關閉檔案
下面是一個具體的樣本程式:
1.操作完成後自動關閉檔案的 with open(‘db’,'r')as f: data = f.read() #一次性將檔案中的內容讀從磁碟上載入到記憶體裡面 data = f.readline() #每次唯讀取一行資料 data = f,write() #對檔案進行寫入的操作2.需要手動關閉檔案的 f = open('db','r') f.read() #對檔案進行讀取的操作 f.close() #關閉檔案View Code
2. 檔案的開啟模式
檔案開啟的格式: 檔案控制代碼 = open('檔案路徑', '模式')
開啟檔案時,需要指定檔案路徑和以何等方式開啟檔案,開啟後,即可擷取該檔案控制代碼,日後通過此檔案控制代碼對該檔案操作。
開啟檔案的模式有:
- r ,唯讀模式【預設模式,檔案必須存在,不存在則拋出異常】
- w,唯寫模式【不可讀;不存在則建立;存在則清空內容】
- x, 唯寫模式【不可讀;不存在則建立,存在則報錯】
- a, 追加模式【可讀; 不存在則建立;存在則只追加內容】
"+" 表示可以同時讀寫某個檔案
- r+, 讀寫【可讀,可寫】
- w+,寫讀【可讀,可寫】
- x+ ,寫讀【可讀,可寫】
- a+, 寫讀【可讀,可寫】
"b"表示以位元組的方式操作
- rb 或 r+b
- wb 或 w+b
- xb 或 w+b
- ab 或 a+b
註:以b方式開啟時,讀取到的內容是位元組類型,寫入時也需要提供位元組類型,不能指定編碼。
檔案操作的執行個體:
import timewith open('db','r')as f: # line = f.read() #一次性輸出到記憶體中等待調用 # line = f.readline() #每次只能輸出一行到記憶體中 # line = f.readlines() #以列表的形式輸出到記憶體中,每一行都是列表中的一個元素(分行符號也是輸出的) #line = f.readlines()#以列表的形式輸出到記憶體中,每一行都是列表中的一個元素(分行符號也是輸出的) for line in f: #通過for 迴圈來實現一行行的輸出,並且取消檔案中每一行的分行符號操作 data =line.strip() time.sleep(1) print(data)View Code
檔案讀寫操作的常用模式:
with open('db','w')as f:# w模式就是以覆蓋的方式寫入 f.write('dafkhfkk')with open('db','a')as f: f.write('我是總') # a模式就是以追加的方式寫入(只能寫到檔案的尾部)r或rt 預設模式,文字模式讀rb 二進位檔案 w或wt 文字模式寫,開啟前檔案儲存體被清空wb 二進位寫,檔案儲存體同樣被清空 a 追加模式,只能寫在檔案末尾a+ 可讀寫入模式,寫只能寫在檔案末尾 w+ 可讀寫,與a+的區別是要清空檔案內容r+ 可讀寫,與a+的區別是可以寫到檔案任何位置View Code
3.open函數詳解:
1. open()文法
open(file[, mode[, buffering[, encoding[, errors[, newline[, closefd=True]]]]]])
open函數有很多的參數,常用的是file,mode和encoding
file檔案位置,需要加引號
mode檔案開啟模式,見下面3
buffering的可取值有0,1,>1三個,0代表buffer關閉(只適用於二進位模式),1代表line buffer(只適用於文字模式),>1表示初始化的buffer大小;
encoding表示的是返回的資料採用何種編碼,一般採用utf8或者gbk;
errors的取值一般有strict,ignore,當取strict的時候,字元編碼出現問題的時候,會報錯,當取ignore的時候,編碼出現問題,程式會忽略而過,繼續執行下面的程式。
newline可以取的值有None, \n, \r, ”, ‘\r\n',用於區分分行符號,但是這個參數只對文字模式有效;
closefd的取值,是與傳入的檔案參數有關,預設情況下為True,傳入的file參數為檔案的檔案名稱,取值為False的時候,file只能是檔案描述符,什麼是檔案描述符,就是一個非負整數,在Unix核心的系統中,開啟一個檔案,便會返回一個檔案描述符。
2. Python中file()與open()區別
兩者都能夠開啟檔案,對檔案進行操作,也具有相似的用法和參數,但是,這兩種檔案開啟檔案有本質的區別,file為檔案類,用file()來開啟檔案,相當於這是在構造檔案類,而用open()開啟檔案,是用python的內建函數來操作,建議使用open
4.檔案部分的總結:
檔案部分的總結1,常用的讀寫方式:r 唯讀模式;w 唯寫的模式(每次寫入內容會覆蓋掉上一次的內容);a 是在末尾以追加的方式進行寫入(不會覆蓋之前寫入的內容)2.可讀可寫的方式:r+ 預設游標在開始的位置,寫的是追加的寫入w+ 覆蓋的形式寫入,想讀取內容,必須對seek進行調整a+ 游標預設在檔案的最後的位置,不管游標位置,一定是追加的寫入,想讀取內容必須對seek 進行調整3.rb wb ab 二進位的形式進行操作
二、函數的基礎知識
1.python中函數定義:函數是邏輯結構化和過程化的一種編程方法。我個人對函數的理解就是:函數其實就是在實現我們的主邏輯過程中的一個個工具,負責一個個具體功能的實現(主要還是處理中間資料為主,返回最終的處理結果返回主邏輯等待調用)
2.Python中:函數的定義基本方法:
def func(x1,x2): x = x1 + x2 return xret = func(2,3)print(ret)def:定義函數的關鍵字func:函數名():內可定義形參"":文檔描述(非必要,但是強烈建議為你的函數添加描述資訊)x = x1 + x2:泛指代碼塊或程式處理邏輯return:定義傳回值調用運行:可以帶參數也可以不帶func()ret 接收的是函數return的傳回值,若函數沒有傳回值則ret接收的是None
View Code
幾點說明:
1程式設計語言中的函數是通過一個函數名封裝好一串用來完成某一特定功能的邏輯,程式設計語言中的函數傳入的參數相同傳回值可不一定相同且可以修改其他的全域變數值(因為一個函數a的執行可能依賴於另外一個函數b的結果,b可能得到不同結果,那即便是你給a傳入相同的參數,那麼a得到的結果也肯定不同)。
2.函數式編程就是:先定義一個數學函數(數學建模),然後按照這個數學模型用程式設計語言去實現它。
3.使用函數編程的幾點優點:
3.1.代碼重用
3.2.保持一致性,易維護
3.3.可擴充性
4.函數的參數問題:
def func(x1,x2): x = x1 + x2 return xret = func(2,3)print(ret)此函數中x1,x2 就是形式參數,而2,3就是實際參數。
View Code
x,y 就是說的形參;a,b就是實參分配記憶體空間,調用結束後就是釋放分配的記憶體空間,# so,形參只有在函數內部有效,函數調用結束後返回主函數後就不能使用此形參變數#3.2實際參數可以是常量、變數、運算式、函數等,無論是什麼,他們必須有確定的值,以便把參數傳遞給形式參數。while True: a=int(input('親輸入a:')) b=int(input('親輸入b:')) def tank(x,y): res = x**y return res c = tank(a,b) print(c)
5.函數值的傳遞問題:
#1、位置參數(參數是一一對應的)def function(x,c,z): y = x+c+z return yres = function(2,3,4)print(res)#2、關鍵字調用(無需對應,自己指定)def function(x,c,z): y = x+c+z return yres = function(c=2,x=3,z=4)print(res)#3、#傳遞預設參數(當實際參數沒有指定值時就使用x4=5,若有指定的時候就 用指定的數值)def func(x1,x2,x4=5): x = x1 + x2 +x4 return xret = func(2,3)print(ret) #10def func(x1,x2,x4=5): x = x1 + x2 +x4 return xret = func(2,3,10)print(ret) #15#4.3、萬能參數使用#4.3.1 args返回的是一個元群組類型,kwargs返回的是一個字典類型def function(x,*args,**kwargs): y =x return y,args,kwargsres = function(1,2,3,4,5,a =5,b =3)print(res) # (1, (2, 3, 4, 5), {'a': 5, 'b': 3})#
6.全域變數與局部標量
# #5.1若函數體內沒有global 關鍵字,
# # 則優先讀取局部變數,若沒有局部變數則向上一個層級去找;可以讀取全域變數
# # 但是不能對全域變數進行賦值操作,ge:name ='kjk'
# #5.2 若函數體內有global 關鍵字,
# #此時的變數本質就是全域變數,可以讀取和賦值操作
name = '就是你'def func1(): name ='a' def func2(): global name name = 'b' print(name) func2() print(name)print(name)func1()print(name)# 執行結果:# 就是你# b# a# b
對函數即是變數的理解:
def action(): print 'in the action' logger()action()報錯NameError: global name 'logger' is not defineddef logger(): print 'in the logger'def action(): print 'in the action' logger() action() def action(): print 'in the action' logger()def logger(): print 'in the logger' action()
7.遞迴調用:如果一個函數在其本身內部調用自己這就叫做遞迴函式,若果在函數內部調用函數(def 裡面還有 def 這樣的叫函數嵌套)
遞迴調用的例子:
#6.1 執行個體一# def func(n):# print(n)# if int(n/2) == 0:# return# res = func(int((n/2)))# return res## a = func(10)# print(a,) 輸出結果為:10521None
實現的步驟為:
遞迴特性:
1. 必須有一個明確的結束條件
2. 每次進入更深一層遞迴時,問題規模相比上次遞迴都應有所減少
3. 遞迴效率不高,遞迴層次過多會導致棧溢出(在電腦中,函數調用是通過棧(stack)這種資料結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由於棧的大小不是無限的,所以,遞迴調用的次數過多,會導致棧溢出)
8.匿名函數:匿名函數就是不需要顯示的指定函數
lamdba函數:ret = lamdba 變數1,變數2.....:運算式 將運算式計算的結果返回給ret
#這段代碼def calc(n): return n**nprint(calc(10)) #換成匿名函數calc = lambda n:n**nprint(calc(10))
9.函數式編程:
9.1 高階函數
滿足倆個特性任意一個即為高階函數
1.函數的傳入參數是一個函數名
2.函數的傳回值是一個函數名
#1.傳回值中包含函數名def test1(): print('in the test1')def test(): print('in the test') return test1res = test()print(res)ret =res()print(ret)
in the test
<function test1 at 0x02199588>
in the test1
None
#1.2name = 'alex'def foo(): name = 'linhaifeng' def bar(): name = 'wupeiqi' print(name) return barprint(name)a = foo()print(a)b =a()print(b)輸出結果:alex<function foo.<locals>.bar at 0x005E94B0>wupeiqiNone
map函數:
#函數方法實現map函數將列表中的每個元素平方再返回這個列表'''num_l = [1,2,3,4,5,6]def map_test(array): ret = [] for i in num_l: ret.append(i**2) return retret = map_test(num_l)print(ret)#終極版本# num_l = [1,2,3,4,5,6,7,8]## def map_test(func,arry): #func = lambda運算式 arry = num_l# ret = []# for i in arry:# res = func(i) #add_one(實現)# ret.append(res)# return ret## res = map_test(lambda x:x+1,num_l)# print(res)# msg = 'linghaifeng'# print(list(map(lambda x:x.upper(),msg)))
輸出結果為:['L', 'I', 'N', 'G', 'H', 'A', 'I', 'F', 'E', 'N', 'G']
filter函數(出去自己不想要的內容)
#1.原理篇# movice_people = ['sb_qwe','sb_rty','sb_kjl','fgd']## def filter_test(arry):# ret = []# for p in arry:# if not p.startswith('sb'):# ret.append(p)# return ret# print(filter_test(movice_people))#通過自製的filter_test函數實現判斷以什麼結尾的功能# movice_people1 = ['qwe_sb','dre_sb','dfg','sb_dfg']# def show_sb(n):# return n.endswith('sb')## def filter_test(func,arry):# ret = []# for p in arry:# if not func(p):# ret.append(p)# return ret## res = filter_test(show_sb,movice_people1)# print(res)#通過lambda函數實現篩選的功能# def filter_test(func,arry):# ret = []# for p in arry:# if not func(p):# ret.append(p)# return ret## res = filter_test(lambda n:n.endswith('sb'),movice_people1)# print(res)#直接通過filter 函數實現篩選功能# ret = filter(lambda n:n.endswith('sb'),movice_people1)#print(ret)# print(list(ret))#把ret轉化成列表的形式# for i in ret:# print(i)輸出結果為:<filter object at 0x021046F0>['qwe_sb', 'dre_sb']
reduce函數:就是對資料進行合并,並對資料壓縮最後得出一個最終的結果
#1.實現reduce函數的功能# num_k = [1,2,3,100]# def reduce_test(arry):# res = 0# for num in arry:# res +=num# return res# print(reduce_test(num_k))## #2.實現列表中元素的相乘# num_k = [1,2,3,4,100]## def multip(x,y):# return x*y# def reduce_rest(func,arry):# res=arry.pop(0)# for num in arry:# res = func(res,num)# return res# print(reduce_rest(multip,num_k))# print(reduce_rest(lambda x,y:x*y,num_k))
#3.函數參數含有預設參數的情況(比如在進行自動化安裝的時候,不必要的確認值就可以設定成預設參數)
#
# num_k = [1,2,3,4,100]
#
# def reduce_rest(func,arry,init=None):
# if init is None:
# res = arry.pop(0)
# else:
# res = init
# for num in arry:
# res = func(res,num)
# return res
# print(reduce_rest(lambda x,y:x*y,num_k),100)
# print(reduce_rest(lambda x,y:x*y,num_k),)
#
# #4.reduce 函數的使用
# from functools import reduce
# num_h = [1,2,3,100]
# ret =reduce(lambda x,y:x+y,num_h)
# print(ret)