1. 文件處理
1.1 文件處理流程
1.打開文件,得到文件句柄并賦值給一個變量
2.通過句柄對文件進行操作
3.關閉文件
1.2 文件讀取模式r
r文本模式的讀,在文件不存在,不會創建新文件
f = open('a.txt','r',encoding='utf-8') f.readable() # 判讀文件是否可讀 f.writable() # 判讀文件是否可寫 f.readline() # 一次讀取一行 f.readlines() # 一次讀取所有值 f.close()?
1.3 文件讀取模式rb
python讀取文件內容。 b模式直接從硬盤中讀取bytes,不用指定編碼格式;以什么格式存的文件,以什么格式讀取文件
f = open('a.txt','rb') print(f.read().decode('utf-8')) f.close()?
1.4 文本寫模式 w
w文本模式的寫,文件存在則清空,不存在則創建
f = open('a.txt','w',encoding='utf-8') f.writable() # 判斷是否可寫 f.readable() # 判斷是否可讀 f.write('你好') # 寫單個值 f.writelines(['aaa\n','bbb\n']) # 寫列表 f.writelines(('111\n','222\n')) # 寫元組 f.close()?
1.5 文件追加模式a
a 文件模式的追加,文件存在、光標跳到文件末尾,文件不存在創建
f = open('a.txt','a',encoding='utf-8') print(f.tell()) # 打印文件光標的位置 f.write('3333\n') f.write('4444\n') f.close()
?
1.6 混合模式
"+" 表示可以同時讀寫某個文件
python常用函數? r+???? 可讀寫文件,即可讀、可寫、可追加
w+??? 可寫讀文件,即可寫、可讀、可追加
a+???? 同a
混合模式不常用,了解即可。
1.7 b模式
#rb模式直接從硬盤中讀取bytes f = open('a.txt','rb') print(f.read()) f.close()#wb模式 f = open('a.txt','wb') f.write('你好'.encode('utf-8')) f.close()?
1.8 遍歷文件
在內存中,同時只有一條內容,不依賴索引;文件很多,用循環遍歷的方式讀取文件。
with open('a.txt','r',encoding='utf-8') as f:for line in f.read():print(line)?
1.9 Copy文件
python調用另一個文件的變量。 利用r模式,模擬Copy動作;以b的方式打開文件,不會涉及文件編碼的問題,b是Bytes的格式;利用r進行處理文件路徑,以后經常需要處理文件路徑的問題,也就是右斜杠沒有特殊意義。
import sysif len(sys.argv) < 3:print('Usage:python3 copy.py source.file target.file')sys.exit()with open(r'%s' %sys.argv[1],'rb') as f_read,\open(r'%s' %sys.argv[2],'wb') as f_write:for line in f_read:f_write.write(line)
?
1.10 文件其他操作
1.10.1 read
例如:read(3)
1.文件打開方式為文本模式時,代表只讀取3個字符。
f = open('a.txt','r',encoding='utf-8') print(f.read(3)) f.close()
?
python查看變量類型。 2.文件打開方式為b模式時,代表讀取3個字節。
f = open('a.txt','rb') print(f.read(6).decode('utf-8')) print(f.read(3).decode('utf-8')) f.close()?
1.10.2 seak
以字節為單位,進行移動光標,有三種模式,三種模式默認指定的參照物不同;其中1、2模式必須在b模式下進行。
0模式:默認以文件開頭為光標移動,參照物為文件開頭
1模式:以當前光標所在的位置為參照物
2模式:以文件結尾為參照物,進行文件光標的移動
# seek的0模式 默認為0模式 f = open('a.txt','r') print(f.read(3)) print(f.tell()) f.seek(3) print(f.tell()) print(f.read())# seek的1模式 f = open('a.txt','rb') print(f.read(3)) print(f.tell()) f.seek(3,1) print(f.tell()) print(f.read().decode('utf-8'))# seek的2模式 f=open('a.txt','rb') f.seek(0,2) print(f.tell()) print(f.read())
1.10.3 tell
多個python文件相互調用、 tell是告訴光標的位置,tell編譯器的具體實現:
def tell(self, *args, **kwargs): # real signature unknown"""Current file position.Can raise OSError for non seekable files."""pass?
1.10.4 truncate
truncate是截斷文件,所以文件的打開方式必須可寫,但是不能用w、w+等方式打開,因為那樣直接清空文件,所以truncate要在r+、a、a+等模式使用;
with open('a.txt','r+',encoding='utf-8') as f:f.truncate(2)?
1.10.5 類似于tail命令
以rb方式打開文件,光標移動到最后:f.seek(0,2)
# tail.py -f access.log import time import syswith open(r'%s' % sys.argv[2], 'rb') as f:f.seek(0, 2)while True:line = f.readline()if line:print(line.decode('utf-8'),end='')else:time.sleep(0.5)?
1.11 總結
???????? 最常用的模式:r、w、a
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? rb、wb、ab
python處理文件,???????? 文件的其他模式,了解即可
2.函數
2.1 不用函數的問題
???????? 復雜度增大
???????? 組織結構不清晰
???????? 可讀性差
?
python調用文件。???????? 代碼冗余
???????? 可擴展性差
?
?如何解決問題:
???????? 利用函數進行解決問題。例如修改下水道的問題:需要準備工具;利用工具與函數進行類比:
python處理文本文件,???????? 1.工具就是具備某一種功能的物件,就是程序中的函數的概念
???????? 2.事先準備工具的過程稱為函數的定義
???????? 3.遇到特定的場景拿來就用稱為函數的調用
?
2.2 函數的分類
在python中,函數的分類有兩種:
python函數定義、 1. 內置函數
2. 自定義函數
例如:python內置的函數(len、print、max)
2.3 原則
函數的使用原則:
1.先定義
python引用文件????????? 2.再調用
2.4 直觀感受使用函數
''' ********************** hello jack ********************** '''def print_star():print('*'*20)def print_msg():print('hello jack')print_star() print_msg() print_star()?
2.5 函數使用
函數的定義與變量的定義類似,沒有事先定義變量,而直接引用變量,會報錯
沒有事先定義函數,而直接調用,就相當于在引用一個不存在的變量名
''' 函數的使用:1 先定義2 再調用 '''#定義階段 def foo():print('from foo')bar() def bar():print('from bar')#調用階段 foo()
函數在定義階段發生了什么事情??
函數在定義階段:只檢測語法,不執行代碼
def func():asdf #asdf=’bbbb’ func()
2.6 函數定義
#函數的定義語法 ''' def 函數名(arg1,arg2,arg3):"注釋"函數體return 返回值函數名一般是動詞 參數 return:函數內部可以有多個return,但只能執行一次,函數就結束調用,并且會把return后的值作為函數執行的結果返回 '''?
2.6.1函數定義三種形式
Python 函數? 無參:???? 應用場景僅僅只是執行一些操作,比如與用戶交互,打印
有參:???? 需要根據外部傳進來的參數,才能執行相應的邏輯,比如統計長度,求最大值
空函數:設計代碼結構
2.6.2 無參函數
def foo():print('from foo')?
2.6.3 有參函數
# 求最大值的函數,類似于python內置函數max def my_max(x,y):if x > y:return xelse:return yres=my_max(1,2) print(res)?
2.6.4 空函數
# sql解析,首先設計sql解析框架 def select(sql):'''select function'''print(sql)#sql=['select', '*', 'from', 'mysql.user;']def insert(sql):'''insert function'''passdef update(sql):'''update function'''passdef delete(sql):'''delete function'''pass#select * from mysql.user; def main():while True:sql=input('>>: ').strip()if not sql:continuecmd_info=sql.split()cmd=cmd_info[0]if cmd == 'select':select(cmd_info)main()?
2.7 函數return
return,是函數結束的標志
return的返回值沒有類型限制
1. 沒有return:返回None,等同于return None
2. return 一個值:返回該值
3. return val1,val2,val3:返回(val1,val2,val3)
?
需要返回值:
調用函數,經過一系列的操作,最后得到一個確定的結果,則必須要有返回值
通常有參函數要有返回值,輸入參數,經過計算,得到一個最終結果
??不需要返回值:
調用函數,僅僅只是執行一系列的操作,最后不需要得到結果,無序有返回值
通常無參函數不需要有返回值
#函數的返回值,返回多個值 def func():print('from func')return [1,2,3],'a',1,{'a':3}
?
2.8 函數調用
函數的調用,有三種形式:
1.語句形式
2.表達式形式
3.函數調用當做另一個函數的參數
def my_max(x,y):if x > y:return xelse:return ymy_max(1,2) # 語句形式 res=my_max(1,2)*10 # 表達式形式 res2=my_max(my_max(1,2),3) # 函數調用可以當做另外一個函數的參數?
2.9 函數參數
函數的參數,分兩種
? ??????? 1.形參:在定義函數時,括號內的參數,形參就是變量名
???????? 2.實參:在調用函數時,括號內的參數,實參就是變量值
在調用階段實參(變量值)才會綁定形參(變量名),調用結束,解除綁定
#形參:在定義函數時,括號內的參數成為形參 #特點:形參就是變量名 def foo(x,y): #x=1,y=2print(x)print(y)#實參:在調用函數時,括號內的參數成為實參 #特點:實參就是變量值 foo(1,2)#在調用階段實參(變量值)才會綁定形參(變量名) #調用結束后,解除綁定?
2.10 參數分類
2.10.1 位置參數
位置參數:按照從左到右的順序依次定義的參數
1.位置形參:必須被傳值,并且多一個不行,少一個也不行
2.位置實參:與形參按照位置一一對應
def foo(x,y):print(x)print(y) foo(1,2)def register(name,age):print(name)print(age) register('jack',18)?
2.10.2 關鍵字參數
關鍵字實參:指的是按照name=value的形式,指名道姓地給name傳值
關鍵字參數需要注意的問題:
問題一:語法規定位置實參必須在關鍵字實參的前面
問題二:一定不要對同一個形參傳多次值
def foo(name,age):print(name)print(age) foo(age=18,name='jack')#關鍵字實參需要注意的問題是: def foo(name,age,sex):print(name)print(age)print(sex)# 正常傳值 foo('jack',18,'male') foo(sex='male',age=18,name='jack') foo('jack',sex='male',age=18)#問題一:語法規定位置實參必須在關鍵字實參的前面 foo('jack',sex='male',age=18)#問題二:一定不要對同一個形參傳多次值 foo('jack',sex='male',age=18,name='jack1') foo('male',age=18,name='jack1')
?
2.10.3 默認參數
默認參數,即默認形參:在定義階段,就已經為形參賦值,意味在調用階段可以不用傳值
使用默認參數,可以降低函數使用的復雜度。
def foo(x,y=222):print(x)print(y)foo('jack') foo(1,'a')def register(name,age,sex='male'):print(name,age,sex)register('jack',73) register('tom',38) register('mary',28,'female')
默認參數需要注意的問題
問題一:默認參數必須放在位置參數之后
def foo(y=1, x):print(x, y)?
問題二:默認參數只在定義階段賦值一次,而且僅一次
x=100 def foo(a,b=x):print(a,b)x=22222 foo('jack')?
問題三:默認參數的值應該定義成不可變類型
不可變類型:包括字符串、數字、元組
可變類型:???? 列表、字典
2.11 可變長參數
可變長參數指的是實參的個數不固定(個數多了)
實參無非位置實參和關鍵字實參兩種
形參必須要兩種機制分別處理:
按照位置定義的實參溢出的情況???????? *
按照關鍵字定義的實參溢出的情況???? **
2.11.1 位置參數
多出來的位置實參,會交給*處理,保存成元組的形式,*把多出來賦值給args
def foo(x,y,*args): #args=(3,4,5,6,7)print(x)print(y)print(args)foo(1,2,3,4,5,6,7) #* foo(1,2) #*
*args的擴展用法
* 處理的是位置參數
* 可以存在于形參位置,*也可以在于實參位置
碰到*位于實參位置,打回原形,拆成位置參數
例如:foo(1,2,*(3,4,5,6,7))? <====>? foo(1,2,3,4,5,6,7)
def foo(x,y,*args): # *args = *(3,4,5,6,7)print(x)print(y)print(args) foo(1,2,3,4,5,6,7) # * foo(1,2,*(3,4,5,6,7)) # 等價于foo(1,2,3,4,5,6,7)def foo(x,y,*args): # print(x)print(y)print(args) foo('a','b',*(1,2,3,4,5,6,7)) # 等價于foo('a','b',1,2,3,4,5,6,7) foo('jack',10,2,3,4,5,6,9)?
2.11.2 關鍵字參數
多出來的關鍵字實參,會交給**處理,保存成字典形式,**把多出來的參數交給kwargs
def foo(x,y,**kwargs): #kwargs={'z':3,'b':2,'a':1}print(x)print(y)print(kwargs) foo(1,2,z=3,a=1,b=2) #**?
**kwargs的擴展用法
** 處理的是關鍵字參數
** 可以存在于形參位置,**也可以在于實參位置
碰到**位于實參位置,打回原形,拆成關鍵字參數
例如:foo(1,2,**{'z':3,'b':2,'a':1}) ?<====> ?foo(1,2,a=1,z=3,b=2)
def foo(x,y,**kwargs): # kwargs={'z':3,'b':2,'a':1}print(x)print(y)print(kwargs) foo(1,2,**{'z':3,'b':2,'a':1}) # foo(1,2,a=1,z=3,b=2)def foo(x, y):print(x)print(y) foo(**{'y':1,'x':2}) # foo(y=1,x=2)?
2.11.3 混合使用
def foo(x,*args,**kwargs): # args=(2,3,4,5) kwargs={'b':1,'a':2}print(x)print(args)print(kwargs) foo(1,2,3,4,5,b=1,a=2)
2.11.4 間接調用函數
import timedef register(name,age,sex='male'):print(name)print(age)print(sex)time.sleep(3)def wrapper(*args, **kwargs): #args=('egon',) kwargs={'age':18}start_time=time.time()register(*args, **kwargs)stop_time=time.time()print('run time is %s' %(stop_time-start_time))wrapper('jack',age=26) register('jack',26)?
2.11.5 命名關鍵字參數
命名關鍵字參數,必須是被以關鍵字實參的形式傳值
在*后面定義的形參稱為命名關鍵字參數,必須是被以關鍵字實參的形式傳值;屬于了解內容。
def foo(*args,x):print(x)print(args)foo(1,2,3,4,x='jack')def foo(name,age,*,sex,group):print(name,age,sex,group) foo('jack',18,group='group1',sex='male')def foo(name,age,*,sex='male',group):print(name,age,sex,group) foo('mary',18,group='group1')?
2.12 函數對象
函數是第一類對象:指的是函數可以被當做數據傳遞
1 被賦值
def foo():print('from foo')f=foo print(f) f()?
2 可以當做參數傳入
def wrapper(func):# print(func) func() wrapper(foo)?
3 可以當做函數的返回
def wrapper(func):return func res=wrapper(foo) print(res)?
4 可以當做容器類型的元素
cmd_dic={'func':foo }print(cmd_dic) cmd_dic['func']()?
?