在Python中,打開文件,獲得文件句柄並賦值給一個變量,默認打開模式就爲rpython
f=open(r'a.txt','w',encoding='utf-8') print(f.writable())
經過句柄對文件進行操做
f.write('1111\n') f.write('2222\n') f.writelines(['3333\n','444\n'])
關閉文件
f.close()
一、由應用程序向操做系統發起系統調用open(...)
二、操做系統打開該文件,並返回一個文件句柄給應用程序
三、應用程序將文件句柄賦值給變量f
第一點:
打開一個文件包含兩部分資源:操做系統級打開的文件+應用程序的變量。在操做完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法爲:
一、f.close() #回收操做系統級打開的文件
二、del f #回收應用程序級的變量
其中del f必定要發生在f.close()以後,不然就會致使操做系統打開的文件尚未關閉,白白佔用資源,而python自動的垃圾回收機制決定了咱們無需考慮del f,這就要求咱們,在操做完畢文件後,必定要記住f.close()
爲避免忘記忘記f.close(),使用with關鍵字來幫咱們管理
with open('a.txt','w') as f: pass with open('a.txt','r') as read_f,open('b.txt','w') as write_f: data=read_f.read() write_f.write(data)
強調第二點:
f=open(...)是由操做系統打開文件,那麼若是咱們沒有爲open指定編碼,那麼打開文件的默認編碼很明顯是操做系統說了算了,操做系統會用本身的默認編碼去打開文件,在windows下是gbk,在linux下是utf-8。
這就用到了上節課講的字符編碼的知識:若要保證不亂碼,文件以什麼方式存的,就要以什麼方式打開。
f=open('a.txt','r',encoding='utf-8')
打開文件的模式有(默認爲文本模式)mysql
文件不存在則建立,文件存在那麼在打開文件後馬上將光標移動到文件末尾,進行追加寫linux
f=open(r'b.txt','a',encoding='utf-8') print(f.writable()) f.write('4444\n') f.write('5555\n') f.writelines(['66666\n','7777\n']) f.close()
f=open(r'b.txt','r',encoding='utf-8') print(f.writable()) print(f.read()) print(f.readlines()) print(f.readline(),end='') print(f.readline(),end='') f.close()
with open('b.txt','r',encoding='utf-8') as f: while True: line=f.readline() if len(line) == 0:break print(line) print(f.readline()) print(f.readline()) print(f.readline()) print(f.readline()) print(f.readline()) print(f.readline()) print(f.readline()) print('第八次',f.readline()) # for line in f: print(line)
with open('111.png','rb') as f: print(f.read())
with open('b.txt','rb',) as f: print(f.read().decode('utf-8'))
with open('b.txt','rt',encoding='utf-8') as f: print(f.read())
with open('b.txt','wb') as f: res='中問'.encode('utf-8') print(res,type(res)) f.write(res)
with open('b.txt','ab') as f: res='哈哈哈'.encode('utf-8') print(res,type(res)) f.write(res)
注:以b方式打開時,讀取到的內容是字節類型,寫入時也須要提供字節類型,不能指定編碼sql
#encoding:utf-8 with open('b.txt','rt',encoding='utf-8') as f: print(f.read())
文件的數據是存放於硬盤上的,於是只存在覆蓋、不存在修改這麼一說,咱們平時看到的修改文件,都是模擬出來的效果,具體的說有兩種實現方式:vim
1. 既能夠拷貝文本又能夠拷貝視頻,圖片等文件windows
2. 用戶一旦參數錯誤,打印命令的正確使用方法閉包
提示:能夠用import sys,而後用sys.argv獲取腳本後面跟的參數app
方式一:將硬盤存放的該文件的內容所有加載到內存,在內存中是能夠修改的,修改完畢後,再由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)編輯器
import os with open('info.txt','r',encoding='utf-8') as read_f,open('.info.txt.swap','w',encoding='utf-8') as write_f: data=read_f.read() write_f.write(data.replace('alex','SB')) os.remove('info.txt') os.rename('.info.txt.swap','info.txt')
方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最後用新文件覆蓋源文件函數
import os with open('info.txt', 'r', encoding='utf-8') as read_f, open('.info.txt.swap', 'w', encoding='utf-8') as write_f: for line in read_f: if 'SB' in line: line=line.replace('SB','alex') write_f.write(line) os.remove('info.txt') os.rename('.info.txt.swap', 'info.txt')
cp複製命令的實現
一、源大小的問題:
二、文件打開模式的問題:b
#!/usr/bin/env python import sys _,src_file,dst_file=sys.argv with open(src_file,'rb') as read_f,\ open(dst_file,'wb') as write_f: # data=read_f.read() # write_f.write(data) for line in read_f: write_f.write(line) write_f.flush()
f.read() #讀取全部內容,光標移動到文件末尾
f.readline() #讀取一行內容,光標移動到第二行首部
f.readlines() #讀取每一行內容,存放於列表中
f.write('1111\n222\n') #針對文本模式的寫,須要本身寫換行符
f.write('1111\n222\n'.encode('utf-8')) #針對b模式的寫,須要本身寫換行符
f.writelines(['333\n','444\n']) #文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式
1. 文件打開方式爲文本模式時,表明讀取3個字符
2. 文件打開方式爲b模式時,表明讀取3個字節
注意:
1. seek有三種移動方式0,1,2,其中1和2必須在b模式下進行,但不管哪一種模式,都是以bytes爲單位移動的
2. truncate是截斷文件,因此文件的打開方式必須可寫,可是不能用w或w+等方式打開,由於那樣直接清空文件了,因此truncate要在r+或a或a+等模式下測試效果
with open('a.txt','r',encoding='utf-8') as f: data1=f.read() print('==1==>',data1) print(f.tell()) data2=f.read() print('==2==>',data2)
只有一種狀況光標以字符爲單位:文件以rt方式打開,read(3)
with open('c.txt','rt',encoding='utf-8') as f: print(f.read(6)) print(f.tell()) f.seek(0,0) print(f.read(6)) f.seek(6,0) f.seek(8,0) print(f.read())
with open('c.txt','rb',) as f: f.seek(6,0) # f.seek(8,0) print(f.read())
with open('c.txt','rb') as f: print(f.read(6)) f.seek(2,1) print(f.tell()) print(f.read().decode('utf-8'))
Ø 組織結構不清晰,可讀性差
Ø 代碼冗餘
Ø 可擴展性差
具有某一個功能的工具---》函數
事先準備工具-》函數的定義
拿來就用、重複使用-》函數的調用
ps:先定義後調用
內置函數:len,max(10,11),help(函數名)
自定義函數:def
語法:
def 函數名(參數1,參數2,...):
"""註釋"""
函數體
return 返回值
'''
#'函數便是變量'
def print_tag(): print('*'*20) def print_msg(): #print_msg=<function print_msg at 0x00000000027EA8C8> print('hello world') print(print_msg) print(print_tag) print_tag() print_msg() print_tag()
sex='male' def auth(): sex name=input('name>>: ').strip() password=input('password>>: ').strip() if name =='egon' and password == '123': print('login successfull') else: print('user or password err')
auth()
def bar(): print('from bar') def foo(): print('from foo') bar() foo()
定義階段 def foo(): print('from foo') bar() 定義階段 def bar(): print('from bar') 調用 def bar(): print('from bar')
一、無參:應用場景僅僅只是執行一些操做,好比與用戶交互,打印
二、有參:須要根據外部傳進來的參數,才能執行相應的邏輯,好比統計長度,求最大值最小值
三、空函數:設計代碼結構
def auth(): name=input('name>>: ').strip() password=input('password>>: ').strip() if name =='egon' and password == '123': print('login successfull') else: print('user or password err')
def my_max(x,y): if x >= y: print(x) else: print(y) my_max(1,2)
def auth(name,password): if name =='egon' and password == '123': print('login successfull') else: print('user or password err') def interactive(): name=input('name>>: ').strip() password=input('password>>: ').strip() auth(name,password) interactive()
一、定義時無參,意味着調用時也無需傳入參數
二、定義時有參,意味着調用時則必須傳入參數
def auth(): pass def put(): pass def get(): pass def ls(): pass
無return->None
return 1個值->返回1個值
return 逗號分隔多個值->元組
一、 函數內能夠有多個return,可是隻能執行一次return
二、 執行return函數就馬上結束,而且return的後值當作本次調用的結果返回
調用函數,通過一系列的操做,最後要拿到一個明確的結果,則必需要有返回值
一般有參函數須要有返回值,輸入參數,通過計算,獲得一個最終的結果
調用函數,僅僅只是執行一系列的操做,最後不須要獲得什麼結果,則無需有返回值
一般無參函數不須要有返回值
def foo(x,y): return x+y res=foo(1,2) def my_max(x,y): if x >= y: return x else: return y res=my_max(1,2) print(res)
def foo(): print('first') return 1 print('second') return 2 print('third') return 3 res=foo() print(res)
形參:在定義階段括號內指定的參數,至關於變量名
實參:在調用階段括號內傳入的值稱之爲實參,至關於值
def foo(x,y): #x=1,y=2 print(x,y) foo(1,2)
位置形參:必須被傳值,多一個少一個都不行
位置實參:與形參一一對應傳值
def foo(x,y): print(x,y) foo(2,1)
特色:指名道姓地給形參傳值,再也不依賴與位置
def foo(name,age,sex): print(name,age,sex) foo('egon',18,'male') foo(sex='male',age=18,name='egon',)
注意:
一、 關鍵字實參必須在位置實參的後面
二、 不能爲同一個參數賦值屢次
foo('egon',sex='male',age=18,name='egon')
特色:定義階段已經有值意味着調用階段能夠不用傳值
位置參數一般用於常常變化的參數,而默認參數指的是大多數狀況下都同樣的
def foo(x,y=1): print(x,y) foo(1,2) foo(y=3,x=1) foo(111) foo(x=1111)
def register(name,age,sex='male'): print(name,age,sex) register('egon1',18) register('egon2',18) register('egon3',18) register('alex',38,'female')
注意:
一、默認參數必須放到位置形參的後面
def register(name,sex='male',age,): print(name,age,sex)
二、默認參數的值只在定義時被賦值一次
三、默認的參數的值一般應該是不可變類型
res=1 def foo(x,y=res): print(x,y) res=10 foo('aaaaaaaa')
實參的形式有:位置實參和關鍵字實參,
形參的解決方案:*,**
Ø *args的用法
def foo(x,y,*args): #z=(3,4,5,6) print(x,y) print(args) foo(1,2,3,4,5,6) foo(1,2,*[3,4,5,6]) #foo(1,2,3,4,5,6) foo(*[1,2,3,4,5,6]) #foo(1,2,3,4,5,6) def foo(x,y): print(x,y) foo(*(1,2)) #foo(1,2)
Ø **kwargs
def foo(x,y,**kwargs): #kwargs={'c':5,'a':3,'b':4} print(x,y) print(kwargs) foo(y=2,x=1,a=3,b=4,c=5) foo(y=2,**{'c':5,'x':1,'b':4,'a':3}) #foo(y=2,a=3,c=5,b=4) def foo(name,age): print(name,age) foo(**{'name':'egon','age':18}) foo({'name':'egon','age':18}) def bar(x,y,z): print(x,y,z)
def wrapper(*args,**kwargs): #args=(1,),kwargs={'z':2,'y':3} # print(args,kwargs) bar(*args,**kwargs) #bar(*(1,),**{'z':2,'y':3}) #bar(1,z=2,y=3,) wrapper(1,z=2,y=3)
def foo(x,y,*args,m=100000,n): print(x,y) print(args) print(m,n) foo(1,2,3,n=4,)
def func(x,y): print(x,y) f=func f(1,2)
def foo(): print('from foo') def bar(func): # print(func) func() bar(foo)
def foo(): print('from foo') def bar(): return foo f=bar() f()
def foo(): print('from foo') def bar(): return foo l=[foo,bar] print(l) l[0]()
def get(): print('get') def put(): print('put') def ls(): print('ls') cmd=input('>>: ').strip() if cmd == 'get': get() elif cmd == 'put': put() elif cmd == 'ls': ls() def get(): print('get') def put(): print('put') def ls(): print('ls') def auth(): print('auth') func_dic={ 'get':get, 'put':put, 'ls':ls, 'auth':auth } # func_dic['put']() cmd = input('>>: ').strip() if cmd in func_dic: func_dic[cmd]()
def my_max(x,y): if x >= y: return x else: return y
def my_max4(a,b,c,d): res1=my_max(a,b) res2=my_max(res1,c) res3=my_max(res2,d) return res3
def f1(): def f2(): print('from f2') def f3(): print('from f3') f3() # print(f2) f2() f1()
名稱空間指的是:存放名字與值綁定關係的地方,
內置名稱空間(python解釋器啓動就有):python解釋器內置的名字,max,len,print
全局名稱空間(執行python文件時生效):文件級別定義的名字
x=1 def func():pass import time if x == 1: y=2 #局部名稱空間(函數調用時生效,調用結束失效):函數內部定義的名字 func()
加載順序:內置---》全局----》局部名稱空間
訪問名字的順序:局部名稱空間===》全局----》內置
x=1
print(x)
#print(max) max=2 def func(): # max=1 print(max)
func() x='gobal' def f1(): # x=1 def f2(): # x=2 def f3(): # x=3 print(x) f3() f2() f1()
全局做用域(全局範圍):內置名稱空間與全局名稱空間的名字,全局存活,全局有效,globals()
局部做用域(局部範圍):局部名稱空間的名字,臨時存活,局部有效,locals()
#xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=111111111111111111111 print(globals()) print(dir(globals()['__builtins__'])) print(locals() is globals()) def func(): # yyyyyyyyyyyyyyyyyyyyyyyy=22222222 print(globals()) print(locals()) func() x=100 def func(): global x x=1 func() print(x) x='global' def f1(): # x=1 def f2(): nonlocal x x=0 f2() print('===f1 innter--->',x) f1() print(x)
def outter(): def inner(): print('inner') return inner f=outter() # print(f) def bar(): f() bar()
x=1 def outter(): # x=2 def inner(): print('inner',x) return inner f=outter() # print(f) # x=1111111111111111111111111111111111111111111111111111111111111111111111111111111111 def bar(): x=3 f() # x=1111111111111111111111111111111111111111111111111111111111111111111111111111111111 bar() x=1111111111111111111111111111111111111111111111111111111111111111111111111111111111
閉包函數:
1 定義在函數內部的函數
2 該函數的函數體代碼包含對外部做用域(而不是全局做用域)名字的引用
3 一般將閉包函數用return返回,而後能夠在任意使用
z=1 def outer(): x=1 y=2 def inner(): print(x,y) # print(z) return inner f=outer() print(f.__closure__[0].cell_contents) print(f.__closure__[1].cell_contents) print(f.__closure__)
def bar(): x=111121 y=2222 f() bar()
def foo(x,y): print(x+y) foo(1,2)
def outter(): x=1 y=2 def foo(): print(x+y) return foo f=outter() f()
返回的函數對象,不只僅是一個函數對象,在該函數外還包裹了一層做用域,這使得,該函數不管在何處調用,優先使用本身外層包裹的做用域
延遲計算(原來咱們是傳參,如今咱們是包起來)
import requests #pip3 install requests def get(url): response=requests.get(url) if response.status_code == 200: print(len(response.text)) get('https://www.baidu.com') get('https://www.baidu.com') get('https://www.baidu.com') def outter(url): # url = 'https://www.baidu.com' def get(): response=requests.get(url) if response.status_code == 200: print(len(response.text)) return get baidu=outter('https://www.baidu.com') python=outter('https://www.python.org') # baidu() # baidu() # baidu()
對擴展開放,對修改是封閉
裝飾它人的,器指的是任意可調用對象,如今的場景裝飾器-》函數,被裝飾的對象也是-》函數
一、不修改被裝飾對象的源代碼
二、不修改被裝飾對象的調用方式
在遵循1,2的前提下爲被裝飾對象添加上新功能
錯誤的示範
import time def index(): time.sleep(3) print('welecome to index') def timmer(func): start=time.time() func() stop=time.time() print('run time is %s' %(stop-start)) timmer(index)
import time def index(): time.sleep(3) print('welecome to index') def timmer(func): # func=index #最原始的index def inner(): start=time.time() func() #最原始的index stop=time.time() print('run time is %s' %(stop-start)) return inner index=timmer(index) #index=inner # print(f) index() #inner()
在被裝飾對象正上方單獨一行寫上,@裝飾器名
@deco1 @deco2 @deco3 def foo(): pass foo=deco1(deco2(deco3(foo)))
import time def timmer(func): def inner(): start=time.time() res=func() stop=time.time() print('run time is %s' %(stop-start)) return res return inner @timmer #index=timmer(index) def index(): time.sleep(1) print('welecome to index') return 1111 res=index() #res=inner() print(res)
import time def timmer(func): def inner(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return inner @timmer #index=timmer(index) def index(name): time.sleep(1) print('welecome %s to index' %name) return 1111 res=index('egon') #res=inner('egon') print(res) @timmer #home=timmer(home) def home(name): print('welcome %s to home page' %name) home('egon') #inner('egon')
import time def auth(func): # func=index def inner(*args,**kwargs): name=input('name>>: ').strip() password=input('password>>: ').strip() if name == 'egon' and password == '123': print('login successful') return func(*args,**kwargs) else: print('login err') return inner @auth def index(name): time.sleep(1) print('welecome %s to index' %name) return 1111 res=index('egon') print(res)
#有參裝飾器
import time def auth2(engine='file'): def auth(func): # func=index def inner(*args,**kwargs): if engine == 'file': name=input('name>>: ').strip() password=input('password>>: ').strip() if name == 'egon' and password == '123': print('login successful') return func(*args,**kwargs) else: print('login err') elif engine == 'mysql': print('mysql auth') elif engine == 'ldap': print('ldap auth') else: print('engin not exists') return inner return auth @auth2(engine='mysql') #@auth #index=auth(index) #index=inner def index(name): time.sleep(1) print('welecome %s to index' %name) return 1111 res=index('egon') #res=inner('egon') print(res)
import time def timmer(func): def inner(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res return inner def auth2(engine='file'): def auth(func): # func=index def inner(*args,**kwargs): if engine == 'file': name=input('name>>: ').strip() password=input('password>>: ').strip() if name == 'egon' and password == '123': print('login successful') return func(*args,**kwargs) else: print('login err') elif engine == 'mysql': print('mysql auth') elif engine == 'ldap': print('ldap auth') else: print('engin not exists') return inner return auth @auth2(engine='file') @timmer def index(name): time.sleep(1) print('welecome %s to index' %name) return 1111 res=index('egon') print(res)
from functools import wraps import time def timmer(func): @wraps(func) def inner(*args,**kwargs): start=time.time() res=func(*args,**kwargs) stop=time.time() print('run time is %s' %(stop-start)) return res # inner.__doc__=func.__doc__ # inner.__name__=func.__name__ return inner @timmer def index(name): #index=inner '''index 函數。。。。。''' time.sleep(1) print('welecome %s to index' %name) return 1111 # res=index('egon') # print(res) print(help(index))