Python函數(shù)進階與文件操作詳情
一、作業(yè)回顧
1、格式化輸出與%百分號
以下結(jié)果中,可以正常輸出“50%及格”語句是(B)
A、print(“%d%及格” % (50)) => 回答大部分結(jié)果(Python這種寫法不正確)
B、print(“%d%%及格” % (50)) => 正確結(jié)果
2、字符串切片
定義一個字符串str1 = ‘abcdefg’,使用切片截取字符串str1[3::-2],求返回結(jié)果:(C)
C、‘db’
3、字典的定義
其實字典中的key可以是很多數(shù)據(jù)類型(不可變數(shù)據(jù)類型 => 整型、浮點型、字符串、元組)
my_dict = {} my_dict[1] = 1 my_dict['1'] = 2 my_dict[1.0] = 3 print(my_dict[1] + my_dict['1'] + my_dict[1.0])
二、引用變量與可變、非可變類型
1、引用變量
在大多數(shù)編程語言中,值的傳遞通常可以分為兩種形式“值傳遞與引用傳遞”,但是在Python中變量的傳遞基本上都是引用傳遞。
聊聊變量在內(nèi)存底層的存儲形式
a = 10
第一步:首先在計算機內(nèi)存中創(chuàng)建一個數(shù)值10(占用一塊內(nèi)存空間)
第二步:在??臻g中聲明一個變量,如a
第三步:把數(shù)值10的內(nèi)存地址賦予給變量小a,形成所謂的==“引用關(guān)系”==
如何驗證Python中變量的引用關(guān)系
答:可以使用內(nèi)置方法id(),其參數(shù)就是要顯示的變量信息 => id(變量名稱)
a = 10 print(id(a))
把一個變量賦予給另外一個變量的影響
a = 10 b = a print(id(a)) print(id(b))
運行結(jié)果:
說明:由以上運行結(jié)果可知,當我們把一個變量賦予給另外一個變量時,其兩者指向的內(nèi)存地址相同。
就說明a和b指向了同一塊內(nèi)存空間,原理圖如下:
思考:如果在b = a以后,我們改變了變量a的值,問變量b是否會受到影響?
# a = 10 # print(id(a)) a = 10 b = a a = 100 print(b) # 10 或 100 print(id(a)) print(id(b))
原理圖:
總結(jié):不可變數(shù)據(jù)類型(數(shù)值)在賦值以后,其中一個值的改變不影響另外一個變量,因為兩者指向空間地址不同。
2、Python中可變和非可變數(shù)據(jù)類型
問題1:在Python中一共有幾種數(shù)據(jù)類型?
答:7種,數(shù)值(int整型、float浮點類型)、bool類型(True和False)、字符串類型(str)、元組(tuple 1,2,3)、列表(list [1, 2, 3])、字典(dict {key:value})、集合(set {1, 2})
在Python中,我們可以把7種數(shù)據(jù)類型分為兩大類:可變類型 + 非可變類型
① 非可變類型
數(shù)值(int整型、float浮點類型)
bool類型(True和False)
字符串類型(str)
元組(tuple 1,2,3)
② 可變類型
列表(list [1, 2, 3])
字典(dict {key:value})
集合(set {1, 2})
問題2:如何判斷一個數(shù)據(jù)類型是可變類型還是非可變類型?
在Python中,可變類型與非可變類型主要是通過這個數(shù)據(jù)類型在內(nèi)存中的表現(xiàn)形式來進行定義的。
① 可變類型就是在內(nèi)存中,其內(nèi)存地址一旦固定,其值是可以發(fā)生改變的
a = [1, 2, 3] print(id(a)) # 向內(nèi)存中追加新數(shù)據(jù)(對數(shù)據(jù)進行改變只能通過數(shù)據(jù)類型.方法()實現(xiàn)) a.append(4) print(id(a))
原理圖:
② 非可變類型就是在內(nèi)存中,內(nèi)存地址一旦固定,其值就沒辦法發(fā)生任何改變了
a = 10 print(id(a)) a = 'hello' print(id(a))
原理圖:
3、可變類型與非可變類型在函數(shù)中的應用
可變類型
# 定義一個函數(shù) def func(names): print(names) # 定義一個全局變量 names = ['張三', '李四', '王五'] # 調(diào)用函數(shù) func(names)
原理圖:
綜上所述:可變類型在函數(shù)中,如果在全局或局部中對可變類型進行增刪改操作,其外部和內(nèi)部都會受到影響。
不可變類型
# 定義一個函數(shù) def func(num): num += 1 print(num) # 定義一個全局變量 a = 10 # 調(diào)用函數(shù) func(a) # 在全局作用域中打印a print(a)
綜上所述:不可變類型在函數(shù)中,局部或全局的改變對外部和內(nèi)部都沒有任何影響。
三、函數(shù)遞歸(重點難點)
1、前言
編程思想:如何利用數(shù)學模型,來解決對應的需求問題;然后利用代碼實現(xiàn)對應的數(shù)據(jù)模
算法:使用代碼實現(xiàn)對應的數(shù)學模型,從而解決對應的業(yè)務問題
程序 = 算法 + 數(shù)據(jù)結(jié)構(gòu)
在我們經(jīng)常使用的算法中,有兩種非常常用的算法:遞推算法 + 遞歸算法
,專門用于解決一些比較復雜,但是拆分后相似度又非常高的程序。
2、遞推算法
遞歸算法:遞推算法是一種簡單的算法,即通過已知條件,利用特定條件得出中間推論,直至得到結(jié)果的算法。遞推又分為順推和逆推。
順推:通過最簡單的條件,然后逐步推演結(jié)果
逆推:通過結(jié)果找到規(guī)律,然后推導已知條件
遞推算法案例:斐波那契數(shù)列
1 1 2 3 5 8 13 21 …
① ② ③ ④ ⑤ ⑥ …
第1位為1,第2位為1,第3位為2 = 1 + 1,第4位為3 = 2 + 1,依次類推…第n位結(jié)果為多少?
f(n) = f(n-1) + f(n-2)
提出問題:求斐波那契數(shù)列第15位的結(jié)果?
分析:f(15) = f(14) + f(13)
? f(14) = f(13) + f(12)
? f(13) = f(12) + f(11)
? …
? f(4) = f(3) + f(2) = 3 + 1
? f(3) = f(2) + f(1) = 2
? f(2) = 1
? f(1) = 1
遞推算法:使用while循環(huán)或for循環(huán)
# 遞推算法:根據(jù)已知條件,求結(jié)果(或者根據(jù)結(jié)果求未知條件) def recusive(n): """ 返回斐波那契數(shù)列某一位(n>=1)的結(jié)果 """ if n == 1 or n == 2: return 1 # 開始遞推f(3) = f(2) + f(1) f(4) = f(3) + f(2) ... f(15) = f(14) + f(13) dict1 = {1:1, 2:1} for i in range(3, n+1): # f(3) = f(2) + f(1) # f(i) = f(i-1) + f(i-2) dict1[i] = dict1[i-1] + dict1[i-2] return dict1[n] # 函數(shù)調(diào)用 print(recusive(15))
3、什么是遞歸算法
程序調(diào)用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種算法在程序設計語言中廣泛應用,它通常把一個大型復雜的問題層層轉(zhuǎn)化為一個與原問題相似的規(guī)模較小的問題來求解,遞歸策略只需少量的程序就可描述出解題過程所需要的多次重復計算,大大地減少了程序的代碼量。
① 簡化問題:找到最優(yōu)子問題(不能再小) ② 函數(shù)自己調(diào)用自己
def func(): # 自己調(diào)用自己 func() func()
4、遞歸兩種重要的元素
遞歸有兩個非常重要的概念:
① 遞歸點:找到解決當前問題的等價函數(shù)(先解決規(guī)模比當前問題小一些的函數(shù),依次類推,最終實現(xiàn)對問題的解決) => 有遞有歸
② 遞歸出口:當問題解決的時候,已經(jīng)到達(必須存在)最優(yōu)問題,不能再次調(diào)用函數(shù)了
注:如果一個遞歸函數(shù)沒有遞歸出口就變成了死循環(huán)
5、編寫遞歸三步走
① 明確你這個函數(shù)想要干什么
如:求斐波那契數(shù)列
② 尋找遞歸結(jié)束條件
如:就是在什么情況下,遞歸會停止循環(huán),返回結(jié)果
③ 找出函數(shù)的等價關(guān)系式
如:斐波那契數(shù)列,第n位 f(n) = f(n-1) + f(n-2)
案例1:使用遞歸求斐波那契數(shù)列
第一步:明確這個函數(shù)想要干什么(先定義出來,明確調(diào)用方式)
# 斐波那契數(shù)列 1 1 2 3 5 8 13 21 ... def f(n): # 編寫遞歸代碼求第n位的結(jié)果 # 調(diào)用函數(shù) print(f(15)) # 610
第二步:尋找遞歸的結(jié)束條件
# 斐波那契數(shù)列 1 1 2 3 5 8 13 21 ... def f(n): # 編寫遞歸代碼求第n位的結(jié)果 if n == 1 or n == 2: return 1 # 調(diào)用函數(shù) print(f(15)) # 610
第三步:找出函數(shù)的等價關(guān)系式(最關(guān)鍵的一步)
# 斐波那契數(shù)列 1 1 2 3 5 8 13 21 ... def f(n): # 編寫遞歸代碼求第n位的結(jié)果 if n == 1 or n == 2: return 1 # 找出與斐波那契數(shù)列等價的關(guān)系式 return f(n-1) + f(n-2) # 調(diào)用函數(shù) print(f(15)) # 610
案例2:使用遞歸求N的階乘(如n=100)
階乘是什么?一個正整數(shù)的階乘(factorial)是所有小于及等于該數(shù)的正整數(shù)的積,如:n!=1×2×3×…×(n-1)×n
1! = 1
2! = 1x2 = 2
3! = 1x2x3 = 6
4! = 1x2x3x4 = 24
…
n!=1×2×3×…×(n-1)×n
第一步:明確這個函數(shù)要做什么以及定義函數(shù)以及調(diào)用方式
def f(n): # 編寫遞歸條件 print(f(100))
第二步:尋找遞歸的結(jié)束條件
def f(n): # 編寫遞歸結(jié)束條件 if n <= 2: return n # ...遞歸等式 print(f(100))
第三步:編寫遞歸等價公式(自己要調(diào)用自己)
等價公式 = 找規(guī)律
1! = f(1) = 1
2! = f(2) = 2
3! = f(2)x3 = 6
4! = f(3)x4 = 24
…
n!= f(n-1) * n
def f(n): # 編寫遞歸結(jié)束條件 if n <= 2: return n # ...遞歸等式 return f(n-1) * n print(f(100))
案例3:面試題 => 猴子吃桃問題
猴子吃桃問題。猴子第1天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個。第2天早上又將剩下的桃子吃掉一半,又多吃了一個。以后每天早上都吃了前一天剩下的一半另加一個。到第10天早上想再吃時,就只剩下一個桃子了。求第1天共摘了多少個桃子
第一步:確定函數(shù)主要要完成什么功能,需要傳遞哪些參數(shù),確認調(diào)用方式
def f(n): # 編寫遞歸代碼 # 調(diào)用f函數(shù) print(f(1))
第二步:編寫遞歸的結(jié)束條件(出口)
# 第一步:確定函數(shù)功能 def f(n): # 第二步:編寫遞歸結(jié)束條件(出口) if n == 10: return 1 # 調(diào)用函數(shù) print(f(1))
第三步:找出與這個問題相等的等式關(guān)系
求桃子的剩余數(shù)量?假設法:假設有10個桃子
第1天,10個桃子吃一半,10/2 = 5 + 1 = 6
第2天,4個桃子吃一半,4/2 = 2 + 1 = 3
第3天,再想吃剩1個
第n天,總剩余桃子的數(shù)量 = (第(n+1)天桃子的剩余桃子的數(shù)量 + 1) * 2
# 第一步:確定函數(shù)功能 def f(n): # 第二步:編寫遞歸結(jié)束條件(出口) if n == 10: return 1 # 第三步:尋找與這個問題相似的等價公式 return (f(n+1) + 1) * 2 # 調(diào)用函數(shù) print(f(8))
四、lambda表達式
1、普通函數(shù)與匿名函數(shù)
在Python中,函數(shù)是一個被命名的、獨立的完成特定功能的一段代碼,并可能給調(diào)用它的程序一個返回值。
所以在Python中,函數(shù)大多數(shù)是有名函數(shù) => 普通函數(shù)。但是有些情況下,我們?yōu)榱撕喕绦虼a,也可以定義匿名函數(shù) => lambda表達式
2、lambda表達式應用場景
如果一個函數(shù)有一個返回值,并且只有一句代碼,可以使用 lambda簡化。
3、lambda表達式基本語法
變量 = lambda 函數(shù)參數(shù):表達式(函數(shù)代碼 + return返回值) # 調(diào)用變量 變量()
4、編寫lambda表達式
定義一個函數(shù),經(jīng)過一系列操作,最終返回100
def fn1(): return 100 # 調(diào)用fn1函數(shù) print(fn1) # 返回fn1函數(shù)在內(nèi)存中的地址 print(fn1()) # 代表找到fn1函數(shù)的地址并立即執(zhí)行
lambda表達式進行簡化:
fn2 = lambda : 100 print(fn2) # 返回fn2在內(nèi)存中的地址 print(fn2())
5、編寫帶參數(shù)的lambda表達式
編寫一個函數(shù)求兩個數(shù)的和
def fn1(num1, num2): return num1 + num2 print(fn1(10, 20))
lambda表達式進行簡化:
fn2 = lambda num1, num2:num1 + num2 print(fn2(10, 20))
6、lambda表達式相關(guān)應用
帶默認參數(shù)的lambda表達式
fn = lambda a, b, c=100 : a + b + c print(fn(10, 20))
不定長參數(shù):可變參數(shù)*args
fn1 = lambda *args : args print(fn1(10, 20, 30))
不定長參數(shù):可變參數(shù)**kwargs
fn2 = lambda **kwargs : kwargs print(fn2(name='Tom', age=20, address='北京市海淀區(qū)'))
帶if判斷的lambda表達式
fn = lambda a, b : a if a > b else b print(fn(10, 20))
列表數(shù)據(jù)+字典數(shù)據(jù)排序(重點)
知識點:列表.sort(key=排序的key索引, reverse=True)
students = [ {'name': 'Tom', 'age': 20}, {'name': 'Rose', 'age': 19}, {'name': 'Jack', 'age': 22} ] # 按name值升序排列 students.sort(key=lambda x: x['name']) print(students) # 按name值降序排列 students.sort(key=lambda x: x['name'], reverse=True) print(students) # 按age值升序排列 students.sort(key=lambda x: x['age']) print(students)
執(zhí)行流程:
students = [ {'name': 'Tom', 'age': 20}, {'name': 'Rose', 'age': 19}, {'name': 'Jack', 'age': 22} ] # 按name值升序排列 students.sort(key=lambda x:x['name']) print(students)
五、Python中高階函數(shù)
1、什么是高階函數(shù)
把函數(shù)作為參數(shù)傳入,這樣的函數(shù)稱為高階函數(shù),高階函數(shù)是函數(shù)式編程的體現(xiàn)。函數(shù)式編程就是指這種高度抽象的編程范式。
2、高階函數(shù)的由來
在Python中,abs()
函數(shù)可以完成對數(shù)字求絕對值計算。
① 正數(shù)的絕對值是它本身 ② 負數(shù)的絕對值是它的相反數(shù)
abs()返回的結(jié)果都是正數(shù)
abs(-10) # 10
round()
函數(shù)可以完成對數(shù)字的四舍五入計算。
round(1.2) # 1 round(1.9) # 2
需求:任意兩個數(shù)字,按照指定要求(① 絕對值 ② 四舍五入)整理數(shù)字后再進行求和計算。
def fn1(num1, num2): return abs(num1) + abs(num2) print(fn1(-10, 10))
def fn2(num1, num2): return round(num1) + round(num2) print(fn2(10.2, 6.9))
要求:我們能不能對以上進行簡化,然后合并為同一個函數(shù) => 設計思想(高階函數(shù))
def fn(num1, num2, f): # f代表要傳入的參數(shù)(參數(shù)是一個函數(shù)名,如abs或round) return f(num1) + f(num2) # 絕對值求和 print(fn(-10, 10, abs)) # 四舍五入 print(fn(10.2, 6.9, round))
3、map()函數(shù)
map(func, lst)
,將傳入的函數(shù)變量func作用到lst變量的每個元素中,并將結(jié)果組成新的列表(Python2)/迭代器(Python3)返回。
lst = [1, 2, 3]
func函數(shù):求某個數(shù)的平方,如輸入2返回4,輸入3返回9
map(func, lst)
返回結(jié)果[1, 4, 9]
# 定義一個函數(shù) def func(n): return n ** 2 # 定義一個列表 list1 = [1, 2, 3] # 使用map對lst進行func函數(shù)操作 list2 = list(map(func, list1)) print(list2)
4、reduce()函數(shù)
reduce(func,lst)
,其中func必須有兩個參數(shù)。每次func計算的結(jié)果繼續(xù)和序列的下一個元素做累加計算。> 注意:reduce()傳入的參數(shù)func必須接收2個參數(shù)。
list1 = [1, 2, 3]
def func(a, b):
? return a + b
reduce(func,lst)
則把列表中的每個元素放入func中進行加工,然后進行累加操作
import functools # 定義一個函數(shù) def func(a, b): return a + b # 定義一個列表 list1 = [10, 20, 30, 40, 50] sums = functools.reduce(func, list1) print(sums)
5、filter()函數(shù)
filter(func, lst)函數(shù)用于過濾序列, 過濾掉不符合條件的元素, 返回一個 filter 對象。如果要轉(zhuǎn)換為列表, 可以使用 list() 來轉(zhuǎn)換。
# 定義一個函數(shù)(獲取所有的偶數(shù)) def func(n): return n % 2 == 0 # 定義一個序列 list1 = [1, 2, 3, 4, 5, 6, 7, 8] # 調(diào)用filter函數(shù)進行過濾操作 result = filter(func, list1) print(list(result))
六、文件的概念
1、什么是文件
內(nèi)存中存放的數(shù)據(jù)在計算機關(guān)機后就會消失。要長久保存數(shù)據(jù),就要使用硬盤、光盤、U 盤等設備。為了便于數(shù)據(jù)的管理和檢索,引入了==“文件”==的概念。
一篇文章、一段視頻、一個可執(zhí)行程序,都可以被保存為一個文件,并賦予一個文件名。操作系統(tǒng)以文件為單位管理磁盤中的數(shù)據(jù)。一般來說,文件可分為文本文件、視頻文件、音頻文件、圖像文件、可執(zhí)行文件等多種類別。
2、思考:文件操作包含哪些內(nèi)容呢?
在日常操作中,我們對文件的主要操作:創(chuàng)建文件、打開文件、文件讀寫、文件備份等等
3、文件操作的作用
文件操作的作用就是把一些內(nèi)容(數(shù)據(jù))存儲存放起來,可以讓程序下一次執(zhí)行的時候直接使用,而不必重新制作一份,省時省力。
七、文件的基本操作
1、文件操作三步走
① 打開文件
② 讀寫文件
③ 關(guān)閉文件
2、open函數(shù)打開文件
在Python,使用open()函數(shù),可以打開一個已經(jīng)存在的文件,或者創(chuàng)建一個新文件,語法如下:
f = open(name, mode) 注:返回的結(jié)果是一個file文件對象(后續(xù)會學習,只需要記住,后續(xù)方法都是f.方法())
name:是要打開的目標文件名的字符串(可以包含文件所在的具體路徑)。
mode:設置打開文件的模式(訪問模式):只讀r、寫入w、追加a等。
r模式:代表以只讀模式打開一個已存在的文件,后續(xù)我們對這個文件只能進行讀取操作。如果文件不存在,則直接報錯。另外,r模式在打開文件時,會將光標放在文件的一行。
w模式:代表以只寫模式打開一個文件,文件不存在,則自動創(chuàng)建該文件。w模式主要是針對文件寫入而定義的模式。但是,要特別注意,w模式在寫入時,光標也是置于第一行同時還會清空原有文件內(nèi)容。
a模式:代表以追加模式打開一個文件,文件不存在,則自動創(chuàng)建該文件。a模式主要也是針對文件寫入而定義模式。但是和w模式有所不同,a模式不會清空文件的原有內(nèi)容,而是在文件的尾部追加內(nèi)容。
3、write函數(shù)寫入文件
基本語法:
f.write('要寫入的內(nèi)容,要求是一個字符串類型的數(shù)據(jù)')
4、close函數(shù)關(guān)閉文件
f.close()
5、入門級案例
# 1、打開文件 f = open('python.txt', 'w') # 2、寫入內(nèi)容 f.write('人生苦短,我學Python!') # 3、關(guān)閉文件 f.close()
強調(diào)一下:中文亂碼問題,默認情況下,計算機常用編碼ASCII、GBK、UTF-8
6、解決寫入中文亂碼問題
# 1、打開文件 f = open('python.txt', 'w', encoding='utf-8') # 2、寫入內(nèi)容 f.write('人生苦短,我學Python!') # 3、關(guān)閉文件 f.close()
7、文件的讀取操作
read(size)方法
:主要用于文本類型或者二進制文件(圖片、音頻、視頻…)數(shù)據(jù)的讀取
size表示要從文件中讀取的數(shù)據(jù)的長度(單位是字節(jié)),如果沒有傳入size,那么就表示讀取文件中所有的數(shù)據(jù)。
f.read() # 讀取文件的所有內(nèi)容 f.read(1024) # 讀取1024個字節(jié)長度文件內(nèi)容,字母或數(shù)字,一個占1個字節(jié)長度。中文utf-8占3個字節(jié)長度。
# 1、打開文件 f = open('python.txt', 'r', encoding='utf-8') # 2、使用read()方法讀取文件所有內(nèi)容 contents = f.read() print(contents) # 3、關(guān)閉文件 f.close()
readlines()方法
:主要用于文本類型數(shù)據(jù)的讀取
readlines可以按照行的方式把整個文件中的內(nèi)容進行一次性讀取,并且返回的是一個列表,其中每一行的數(shù)據(jù)為一個元素。
# 1、打開文件 f = open('python.txt', 'r', encoding='utf-8') # 2、讀取文件 lines = f.readlines() for line in lines: print(line, end='') # 3、關(guān)閉文件 f.close()
8、聊聊文件操作的mode模式
模式 | 描述 |
---|---|
r | 以只讀方式打開文件。文件的指針將會放在文件的開頭。這是默認模式。 |
rb | 以二進制格式打開一個文件用于只讀。文件指針將會放在文件的開頭。這是默認模式。 |
r+ | 打開一個文件用于讀寫。文件指針將會放在文件的開頭。 |
rb+ | 以二進制格式打開一個文件用于讀寫。文件指針將會放在文件的開頭。 |
w | 打開一個文件只用于寫入。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
wb | 以二進制格式打開一個文件只用于寫入。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
w+ | 打開一個文件用于讀寫。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
wb+ | 以二進制格式打開一個文件用于讀寫。如果該文件已存在則打開文件,并從開頭開始編輯,即原有內(nèi)容會被刪除。如果該文件不存在,創(chuàng)建新文件。 |
a | 打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進行寫入。 |
ab | 以二進制格式打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進行寫入。 |
a+ | 打開一個文件用于讀寫。如果該文件已存在,文件指針將會放在文件的結(jié)尾。文件打開時會是追加模式。如果該文件不存在,創(chuàng)建新文件用于讀寫。 |
ab+ | 以二進制格式打開一個文件用于追加。如果該文件已存在,文件指針將會放在文件的結(jié)尾。如果該文件不存在,創(chuàng)建新文件用于讀寫。 |
雖然mode文件操作模式很多,但是我們只需要記住3個字符即可。r、w、a
r+、w+、a+,代加號,功能全,既能讀,又能寫(區(qū)別在于指針到底指向不同)
rb、wb、ab,代b的字符,代表以二進制的形式對其進行操作,適合讀取文本或二進制格式文件,如圖片、音頻、視頻等格式
rb+、wb+、ab+,代加號,功能全,既能讀,又能寫(區(qū)別在于指針到底指向不同)
9、seek函數(shù)移動光標
無論是文件讀操作,還是寫操作。其起始位置都是文件光標決定的。
r => 文件頭
w => 清空文件內(nèi)容,指向文件頭
a => 文件尾
光標在剛打開文件時,默認情況下是根據(jù)r、w、a模式相關(guān)固定的。但是我們可以通過某些方法,人為移動光標??梢酝ㄟ^seek方法實現(xiàn)。
f.seek(offset,whence=0)
offset:開始的偏移量,也就是代表需要移動偏移的字節(jié)數(shù)
whence:給offset參數(shù)一個定義,表示要從哪個位置開始偏移;0代表從文件開頭開始算起,1代表從當前位置開始算起,2代表從文件末尾算起
實際工作中,seek主要用于重置光標到起始位置。
f.seek(0) #或 f.seek(0, 0)
其他應用:
>>> f = open('workfile', 'rb+') >>> f.write(b'0123456789abcdef') 16 >>> f.seek(5) # 從0開始向右移動5個字節(jié) 5 >>> f.read(1) b'5' >>> f.seek(-3, 2) # 從右向左移動3個字節(jié) 13 >>> f.read(1) b'd'
八、文件備份案例
1、案例需求
需求:用戶輸入當前目錄下任意文件名,完成對該文件的備份功能(備份文件名為xx[備份]后綴,例如:test[備份].txt)。
實現(xiàn)思路:
① 接收用戶輸入的文件名
② 規(guī)劃備份文件名
③ 備份文件寫入數(shù)據(jù)
2、代碼實現(xiàn)
# 1、接收用戶輸入的文件名(要備份的文件名) oldname = input('請輸入要備份的文件名稱:') # python.txt # 2、規(guī)劃備份文件名(python[備份].txt) # 搜索點號 index = oldname.rfind('.') # 返回文件名和文件后綴 name = oldname[:index] postfix = oldname[index:] newname = name + '[備份]' + postfix # 3、對文件進行備份操作 old_f = open(oldname, 'rb') new_f = open(newname, 'wb') # 讀取源文件內(nèi)容寫入新文件 while True: content = old_f.read(1024) if len(content) == 0: break new_f.write(content) # 4、關(guān)閉文件 old_f.close() new_f.close()
到此這篇關(guān)于Python函數(shù)進階與文件操作詳情的文章就介紹到這了,更多相關(guān)Python文件操作 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python3.6+Django2.0以上 xadmin站點的配置和使用教程圖解
django自帶的admin站點雖然功能強大,但是界面不是很好看。這篇文章主要介紹了Python3.6+Django2.0以上 xadmin站點的配置和使用 ,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-06-06Python openpyxl庫處理Excel文件高級應用技巧實例
openpyxl是一個用于處理Excel文件的Python庫,它提供了豐富的功能,使得用戶能夠輕松地讀取、寫入和操作Excel文件,而不需要依賴于Microsoft Excel軟件,作為一個開源項目,openpyxl在Python生態(tài)系統(tǒng)中得到了廣泛的應用,成為處理Excel數(shù)據(jù)的首選工具之一2024-01-01django 將自帶的數(shù)據(jù)庫sqlite3改成mysql實例
這篇文章主要介紹了django 將自帶的數(shù)據(jù)庫sqlite3改成mysql實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07python的print輸出在控制臺并且將輸出內(nèi)容保存為文件(最新推薦)
這篇文章主要介紹了python的print輸出在控制臺并且將輸出內(nèi)容保存為文件,我感覺就是類似于重寫一下調(diào)用print的時候執(zhí)行的方法,讓他既能夠在控制臺輸出,也能保存到文件里去,需要的朋友可以參考下2023-01-01