python基礎3之文件操作、字符編碼解碼、函數介紹


內容概要:

一、文件操作

二、字符編碼解碼

三、函數介紹

 

一、文件操作

文件操作流程:

  1. 打開文件,得到文件句柄並賦值給一個變量
  2. 通過句柄對文件進行操作
  3. 關閉文件

基本操作:

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 f=open("test","r",encoding="utf-8")#打開文件,並告訴解釋器以那種編碼打開,編碼不對會報錯
5 data=f.read()#操作文件
6 print(data)#打印文件內容
7 f.close()#關閉文件

打開文件模式

  • r ,只讀模式【默認】

  • w,只寫模式【不可讀:不存在則創建;存在則清空內容;】

  • x, 只寫模式【不可讀:不存在則創建,存在則報錯】

  • a, 追加模式【不可讀;不存在則創建;存在則只追加內容;】

“+”表示同時讀寫某個文件,特別注意在操作文件過程中明白文件指針的位置,稍后我會舉例子說明文件針的問題。

  • r+,可讀寫文件【可讀;可寫;可追加】
  • w+,寫讀
  • a+,追加讀

"b"表示處理二進制文件,意思是"b"類型打開的文件讀的內容是字節類型(bytes),若寫入文件也需要是字節類型,需要通過bytes進行轉化。(如:FTP發送上傳ISO鏡像文件,linux可忽略,windows處理二進制文件時需標注)

  • rb
  • wb
  • ab

"U"表示在讀取時,可以將 \r \n \r\n自動轉換成 \n (與 r 或 r+ 模式同使用),在python3中該模式已經廢棄了,2.x版本中保留。

  • rU
  • r+U

示列一(r+模式):

下面着重說明文件指針和讀寫文件的關系,同時演示下以“b”模式打開的文件讀寫操作。

文件內容:

 1 You were the shadow to my light
 2 Did you feel us
 3 Another Star
 4 You fade away
 5 Afraid our aim is out of sight
 6 Wanna see us
 7 Alive
 8 Where are you now
 9 Where are you now
10 Where are you now

示列代碼:

 1 #f.tell() 讀取當前文件指針位置,單位為字符
 2 #f.seek() 重新偏移指針位置,參數為整數
 3 #f.readline()表示讀取一行
 4 #/usr/bin/env python
 5 # -*- coding:utf-8 -*-
 6 #Author:W-D
 7 f=open("test","r+",encoding="utf-8")
 8 print(f.tell())#打印開始的指針位置
 9 data=f.readline()#讀取第一行數據放在data里
10 print(len(data),data)#打印數據長度內容
11 print(f.tell())#打印當前指針位置
12 f.write("")#寫文件內容
13 print(f.tell())#打印指針位置
14 f.close()#關閉文件
15 
16 結果:
17 0
18 28 were the shadow to my light
19 29
20 186
21 
22 修改后的文件變為:
23 
24 were the shadow to my light
25 Did you feel us
26 Another Star
27 You fade away
28 Afraid our aim is out of sight
29 Wanna see us
30 Alive
31 Where are you now
32 Where are you now
33 Where are you now我

結果分析:上述結果表明,以r+模式打開文件,一開始文件指針在0,但讀取一部分內容后文件指針后移動,當使用write方法寫文件時候,文件指針移到了末尾變成最后追加的方式,而並不是在讀取文件時候的指針位置直接寫。

示列二(以r+b):細心的小伙伴可以發現同樣有r+模式,都是讀取后再寫內容,但是以“r+”模式指針移到了最后,追加寫,而以“r+b”則指針不動,接着覆蓋文件內容寫。

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 f=open("test","r+b")#以b模式打開已經確定了編碼不需要在寫encoding  5 print(f.tell())
 6 data=f.readline()
 7 print(type(data),data)
 8 print(f.tell())
 9 f.write(bytes("",encoding="utf-8"))#將字符串轉化為bytes類型
10 print(f.tell())
11 f.close()
12 結果:
13 0
14 <class 'bytes'> b'were the shadow to my light\r\n'#可以看見內容為bytes類型
15 29
16 32

 

附上處理文件時候使用的常用方法:

 1 file.close() #關閉文件。關閉后文件不能再進行讀寫操作。
 2     
 3 file.flush() #刷新文件內部緩沖,直接把內部緩沖區的數據立刻寫入文件, 而不是被動的等待輸出緩沖區寫入。
 4     
 5 file.fileno() #返回一個整型的文件描述符(file descriptor FD 整型), 可以用在如os模塊的read方法等一些底層操作上。
 6     
 7 file.isatty() #如果文件連接到一個終端設備返回 True,否則返回 False。
 8     
 9 file.next() #返回文件下一行(迭代器)。
10     
11 file.read([size]) #從文件讀取指定的字節數,如果未給定或為負則讀取所有。
12 
13 file.readline([size]) #讀取整行,包括 "\n" 字符。
14 
15 file.readlines([sizehint]) #讀取所有行並返回列表,若給定sizeint>0,返回總和大約為sizeint字節的行, 實際讀取值可能比sizhint較大, 因為需要填充緩沖區。
16     
17 file.seek(offset[, whence]) #設置文件當前位置
18 
19 file.tell() #返回文件當前位置。
20 
21 file.truncate([size]) #截取文件,截取的字節通過size指定,默認為當前文件位置。
22 
23 file.write(str) #將字符串寫入文件,沒有返回值。
24 
25 file.writelines(list) #向文件寫入一個序列字符串列表,如果需要換行則要自己加入每行的換行符。

 

文件內容循環:

在對文件的操作過程中,最多的就是讀取並處理文件內容,當文件很大的時候,使用read方法一次性讀取是非常不明智的,不僅處理慢,還耗內存,此時我們可以使用for循環處理。

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 f=open("test","r+",encoding="utf-8")
 5 for line in f:#一行一行循環讀取
 6     print(line.strip())#打印
 7 
 8 結果:
 9 You were the shadow to my light
10 Did you feel us
11 Another Star
12 You fade away
13 Afraid our aim is out of sight
14 Wanna see us
15 Alive
16 Where are you now

 

tps:使用flush實現進度條效果

原理:

使用sys.stdout.write()方法向窗口輸入字符(不換行),在使用flush強制刷新內存,打印在輸出控制台上。

預備知識:

先說一下文本系統的控制符:

  • \r:   將光標移動到當前行的首位而不換行
  • \n:   將光標移動到下一行,並不移動到首位
  • \r\n:  將光標移動到下一行首位
#/usr/bin/env python
# -*- coding:utf-8 -*-
#Author:W-D
import sys,time
for i in range(1,101):
    num="="*i#設置每次打印=好的數量,數量一定要增加
    sys.stdout.write("\r{}>%{}".format(num,i))#"\r"表示每次打印現將光標移動到最前面打印
    sys.stdout.flush()
    time.sleep(0.5)

 

關於with

為避免我們打開了文件進行操作以后沒有關閉,使用with打開文件會自動調用close()方法關閉文件,同時在python2.7以后with也提供了同時打開多個文件的上下文管理。

示列:修改文件

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 with open("test","r",encoding="utf-8") as f1,open("new.txt","w",encoding="utf-8") as f2:
5     for line in f1:
6         f2.write(line)#將f1(test)文件內容寫入到f2(new.txt)中

 

二、字符編碼解碼

首先需要了解的知識:

1.在python2x中默認字符編碼是ASCII, 而在python3里默認是utf-8

2.unicode 分為 utf-32(占4個字節),utf-16(占兩個字節),utf-8(占1-4個字節),utf-8就是unicode

3.在pyhton3中encode,在轉碼的同時還會把string 變成bytes類型,decode在解碼的同時還會把bytes變回string

4.更多的編碼知識請參考http://www.cnblogs.com/yuanchenqi/articles/5956943.html

 

日常疑難雜症狀之windows編碼問題:

以python2.7為例:

python2.7默認字符編碼為ASCII,當我們在腳本文件中指定編碼為utf-8,但是有時候還是會亂碼,示列:

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 test="你好"
5 print(test)

結果:

原因分析:

雖然在代碼中指定了編碼格式,但是dos窗口編碼是gbk,而我們用了utf-8,輸出了亂碼。ps:查看dos窗口編碼方法:點擊窗口-->右鍵-->屬性,在當前頁面欄。

如果這時候我們使用python3來執行當前的腳本,可以輸出中文,因為python3的默認為unicode,unicode兼容gbk。

換個姿勢讓windows輸出中文,這就是接下來要講的編碼解碼(代碼只適用於python2.x):

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 test="你好"
 5 temp=test.decode(encoding="utf-8")
 6 #解碼,首先必須告訴解釋器原來是什么編碼
 7 new_test=temp.encode("gbk")#編碼,編碼為GBK
 8 print(new_test)#輸出
 9 結果:
10 你好

python2中解碼編碼流程如下:

 

由於在python3中默認的字符編碼改為了unicode,所以對於python3中的編碼解碼過程如下:

 

轉碼示列操作

python2中:

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 test="我來了"
5 new_test=test.decode("utf-8").encode("gbk")
6 #decode必須制定當前編碼,由於在腳本頭中指定當前編碼為utf-8,如果腳本頭中沒有指定,會采用系統默認編碼。
7 print(new_test)
8 結果:
9 我來了
python2

 在python3中由於默認編碼改變,並且編碼的時候會將字符串轉為bytes類型,若需要輸出為字符串類型需要解碼。

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  #設置文件編碼為utf-8,為了讓系統識別,如果系統文件編碼為gbk,該文件將不會被識別。
 4 #Author:W-D
 5 import sys
 6 print (sys.getdefaultencoding())#打印當前系統默認編碼(不一定是頭中聲明的編碼)
 7 test="你好"#該變量的編碼是unicode(utf-8),文件編碼如果是gbk,該變量編碼依然不會改變
 8 gbk_test=test.encode("gbk")#轉碼為gbk
 9 print(gbk_test)#打印
10 print(gbk_test.decode("gbk").encode("utf-8"))#gbk轉utf-8
11 print(gbk_test.decode("gbk"))#將gbk解碼為unicode,變成字符串打印
12 結果:
13 utf-8
14 b'\xc4\xe3\xba\xc3'
15 b'\xe4\xbd\xa0\xe5\xa5\xbd'
16 你好
python3

 

三、函數介紹

1.為何使用函數

  • 減少重復代碼
  • 使程序變的可擴展
  • 使程序變得易維護

2.語法

1 def 函數名(參數):
2     ...
3     函數體
4     ...
5     返回值

簡單示列:

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 def  test(a):
5     print("this is %s"% a)
6 test("WD")#調用函數
7 結果:
8 this is WD

 

3.函數參數與局部變量

 

形參:變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數后則不能再使用該形參變量

 

實參:可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值

示列:

1 #/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 #Author:W-D
4 def  test(x,y):#x,y為形參
5     return x+y#x+y返回值
6 a=test(3,5)#返回值保存在a中
7 print(a)
8 結果:
9 8

 

4.函數參數傳遞

 在函數調用的時候,傳遞的參數有兩種,這兩種方式可以單獨使用,也可以混用,但是要注意一個原則關鍵字參數必須放在位置參數之后

1.位置參數,按形參位置來傳遞

2.關鍵字參數,按形參的參數名傳遞

示列:

 

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 def msg(_name,_age,_city):
 5     print("name:{},age:{},city:{}".format(_name,_age,_city))
 6 name="WD"
 7 age=22
 8 city="beijing"
 9 msg(name,age,city)#關鍵字參數傳遞
10 msg(_name=name,_age=age,_city=city)#位置參數傳遞
11 msg(name,_city=city,_age=age)#關鍵字和位置參數同時傳遞
12 結果:
13 name:WD,age:22,city:beijing
14 name:WD,age:22,city:beijing
15 name:WD,age:22,city:beijing

 

 

5.設置默認參數和非固定參數

設置默認參數:作用就是當我們沒有傳遞該參數時候,調用函數會傳遞參數的默認值,當傳遞了該默認參數的值時候,采用傳遞的值。

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 def test(age,name="WD"):#設置name默認值是WD
 5     print(name,age)
 6 test(22) #未傳遞name
 7 test(22,"alex")#傳遞name
 8 結果:
 9 WD 22
10 alex 22

非固定參數:若函數在定義時不確定調用時候想傳入多少個參數,就可以使用非固定參數

語法:

1.*參數(如*args),該形式會將傳入的參數當作數組處理

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 def test(name,age,*args):
 5     print(name,age,args)
 6     print(type(args))
 7 test("wd",22,"a","b","c")
 8 test("jack",38)
 9 結果:
10 wd 22 ('a', 'b', 'c')#將參數作為一個tuple
11 <class 'tuple'>
12 jack 38 ()#不傳參數就作為空tuple
13 <class 'tuple'>
View Code

2.**參數(如**kwargs),該形式會將傳入的參數作為字典處理

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 def test(name,age,**kwargs):
 5     print(name,age,kwargs)
 6     print(type(kwargs))
 7 test("wd",22,jack=22,job="it")#傳遞的時候key相當於變量=號后是值
 8 結果:
 9 wd 22 {'job': 'it', 'jack': 22}
10 <class 'dict'>
View Code

 

6.全局變量與局部變量(這變量為數字,字符串,后面會提及當變量數據類型比較高級的時候,情況不一樣了

  • 在子程序中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。
  • 全局變量作用域是整個程序,局部變量作用域是定義該變量的子程序。
  • 當全局變量與局部變量同名時,在定義局部變量的子程序內,局部變量起作用,在其它地方全局變量起作用。

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 name ="WD"
 5 def change_name(name):
 6     print("before is %s" %name)
 7     name="jack"#局部變量
 8     print("after is %s" %name)
 9 
10 change_name("rose")
11 print("finally is %s "%name)
12 結果:
13 before is rose
14 after is jack
15 finally is WD #未改變全局變量

若要修改全局變量,必須首先使用global聲明(不推薦修改全局變量

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 name ="WD"#全局變量
 5 def change_name(_name):
 6     global name#聲明該變量是全局變量
 7     print("before is %s" %_name)
 8     name="jack"#局部變量
 9     print("after is %s" %_name)
10 
11 change_name("rose")
12 print("finally is %s "%name)
13 結果:
14 before is rose
15 after is rose
16 finally is jack#全局變量修改了

當全局變量為列表,字典,集合,類等這些數據類型的時候,修改局部變量,同樣也修改了全局變量。

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 name =[1,2,3]#列表類型的全局變量
 5 def change_name(_name):
 6     print("before is %s" %_name)
 7     name[0]="修改了嗎"
 8     print("after is %s" %_name)
 9 
10 change_name(name)
11 print("finally is %s "%name)#打印全局變量
12 結果:
13 before is [1, 2, 3]
14 after is ['修改了嗎', 2, 3]
15 finally is ['修改了嗎', 2, 3] #修改了全局變量
View Code

 

7.返回值

如果在默寫場景下,我們要想獲取函數的執行結果,就可以用return語句把結果返回

注意:

  1. 函數在執行過程中只要遇到return語句,就會停止執行並返回結果,也可以理解為 return 語句代表着函數的結束
  2. 如果未在函數中指定return,那這個函數的返回值為None 
  3. 返回值可以是字符串、數字、列表、甚至可以是函數

示列:

 1 #/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3 #Author:W-D
 4 def add(x,y):
 5     print("%d+%d=%d" %(x,y,x+y))
 6     return x>y#返回x>y的結果
 7 a=add(3,4)
 8 print(a)
 9 結果:
10 3+4=7
11 False

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM