python基礎——元組、文件及其它

Python核心數據類型——元組

元組對象(tuple)是序列,它具備不可改變性,和字符串相似。從語法上講,它們便在圓括號中,它們支持任意類型、任意嵌套及常見的序列操做。python

  • 任意對象的有序集合:與字符串和列表相似,元組是一個位置有序的對象集合(內容維持從左到右的順序),能夠嵌入到任何類別的對象中。
  • 經過偏移存取:同字符串、列表同樣,在元組中的元素經過偏移(而不是鍵)來訪問。支持基於偏移的操做。如索引和分片。
  • 屬於不可變序列類型:相似字符串,元組是不可變的,它們不支持應用在列表中任何原處修改的操做。
  • 固定長度、異構、任何嵌套:元組不可變,在不生成一個拷貝的狀況下不能增加或縮短。元組能夠包含其餘的複合對象(例如:列表、字典和其餘元組等),支持嵌套。
  • 對象引用的數組:元組最好看作是對象引用的數組。元組存儲指向其餘對象的存取點(引用),而且對元組進行索引操做的速度相對較快。

常見元組常量和運算shell

運算 解釋
() 空元組
T = (0,) 單個元素的元組(非表達式)
T = (0,’NI’,1.2,3) 四個元素的元組,混合類型
T = 0,’Ni’,1.2,3 四個元素元組,與前列相同
T = (‘abs’,(‘def’,’ghi’)) 嵌套元組
T = tuple(‘spam’) 一個可迭代對象的項轉換爲元組
T[i],T[i][j],T[i:j],len(T) 索引,索引的索引,分片,長度
T1+T2,T * 3 合併,重複(元素項重複)
for x in T : print(x) 迭代
‘spam’ in T 成員關係
[x ** 2 for x in T] 列表解析
T.index(‘Ni’) 搜索
T.count(‘Ni’) 計數
sorted(T) 返回一個排序後的列表
>>> T = (1,2,3,4)
>>> len(T)
4
>>> T + (5,6)
(1, 2, 3, 4, 5, 6)
>>> T[0]
1
>>> T.index(4)
3
>>> T.count(4)
1
>>> T[0] = 2   #元組是不可變的
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> T = ('spam',3.0,[11,22,33])
>>> T[1]
3.0
>>> T[2][1]
22
>>> T.append(4) #不可增加或縮短
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'

元組確實支持字符串和列表的通常序列操做數據庫

>>> (1,2) + (3,4)  #生成新的元組
(1, 2, 3, 4)
>>> (1,2) * 4  #生成新的元組
(1, 2, 1, 2, 1, 2, 1, 2)
>>> T = (1,2,3,4)
>>> T[0],T[1:3] #生成新的元組
(1, (2, 3))

Python核心對象類型——文件

文件對象是Python代碼計算機上外部文件的主要接口。雖然文件是核心類型,但它有些特殊:沒有特定的常量語法建立文件。要建立一個文件對象,須要調用內置的open函數以字符串的形式傳遞給它一個外部的文件名以及一個處理模式的字符串。例如:建立一個文本輸出文件,能夠傳遞其文件名以及’w’處理模式字符串以寫數據:數組

>>> f = open('data.txt','w')   #當前文件夾下建立新文件
>>> f.write('Hello\n')  #把hello字符串寫入文件
6
>>> f.write('world\n')
6
>>> f.close()   #關閉文件

在當前文件夾下建立了一個文件,並向它寫入文本(文件名能夠是完整的路徑)。讀取內容,以‘r’處理模式打開文件。緩存

>>> f.open('data.txt','r')
>>> text = f.read()
>>> text
'Hello\nworld\n'
>>> print(text)
Hello
world

>>> text.split()  #文件內容爲字符串
['Hello', 'world']

常見文件運算

操做 解釋
output = open(r’c:\spam',’w’) 建立輸出文件(‘w’是指寫入)
input = open(‘data’,’r’) 建立輸入文件(‘r’是指讀取)
input = open(‘data’) 與上一行相同(‘r’是默認值)
aString = input.read() 把整個文件讀取到變量
aStrint = input.read(N) 讀取以後的N個字節
aString = input.readline() 讀取下一行(包括末標識符)
aList = input.readlines() 讀取整個文件到字符串列表
output.write(aString) 寫入字節字符到文件
output.writelines(aList) 把列表內全部字符串寫入文件
output.close() 手動關閉文件(當文件手機完成時會替你關閉文件)
output.flush() 把輸出緩衝區刷到硬盤中,但不關閉文件
anyFile.seek(N) 修改文件位置到偏移量N出以便進行下一個操做
for line in open(‘data’):use line 文件迭代器一行一行地讀取
open(‘f.txt’,encoding=’latin-1’) Unicode文本文件(str字符串)
open(‘f.bin’,’rb’) 二進制byte文件(bytes字符串)

打開文件網絡

爲了打開一個文件,程序會調用內置函數open函數,首先是外部名,接着是處理模式。app

語法: python2.7

文件句柄 = open(‘文件路徑+文件名’,’處理模式’)
如:
>>> fp = open(r'c:\data\user_data.txt','r') #以只讀模式打開c:\data\user_data.txt文件

文件按指定模式打開後,經過文件句柄(如:fp)對文件內容進行操做。socket

處理模式典型地用字符串函數

  • ’r’表明爲只讀打開文件(默認值)。
  • ’w’表明爲只寫模式【不可讀;當文件不存時,建立文件;當文件存在時,清空文件內容後再寫】。
  • ’a’表明爲在文件尾部追加內容模式【可追加讀寫;當文件不存在時,建立後寫內容;當文件存在時,在文件內容尾部追加內容】。

處理模式也能夠指定爲其餘選項:

  • 在模式字符串尾部加上b(byte)能夠進行二進制數據處理(行末轉換Unicode被關閉了),讀取到的內容是字節類型,寫入時也須要提供字節類型。
    • ‘rb’
    • ‘wb’
    • ‘ab’
  • 加上「+」意味着同時爲輸入和輸出打開文件(也就是說,咱們能夠對相同文件對象進行讀寫,每每與文件中的修改的查找操做配合使用)
    • ‘r+’:讀寫【可讀,可寫;注意不會建立不存在的文件;若是直接寫文件,則從頂部開始寫,覆蓋以前此位置的內容;若是先讀後寫,則會在文件最後追加內容。
    • ‘w+’:可寫讀。當文件不存時,建立文件;當文件存在時,覆蓋文件後再寫;注意先覆蓋文件(也就是空文件),後面使用讀無心義了
    • ‘a+’:追加寫讀。從文件頂部讀取內容,從文件底部添加內容,文件不存在則建立。

要打開的兩個參數必須都是Python的字符串,第三個是可選參數,它可以用來控制輸出緩存:傳入「0」意味着輸出無緩存(寫入方法調用時當即傳給外部文件)。外部文件參量可能包含平臺特定的以及絕對或相對目錄路徑前綴。沒有目錄路勁時,表示存在當前的工做目錄中(也就是腳本運行的地方)。

使用文件

一旦存在一個文件對象,就能夠調用其方法來讀寫相關的外部文件。在任何狀況下,Python程序中的文本文件都採用字符串的形式。讀取文件是會返回字符串形式的文本,文本做爲字符串傳遞給write方法。

  • 文件迭代器是最好的讀取性工具:雖然表中的讀寫方法都是經常使用的,可是要記住,如今從文本文件讀取文字行的最佳方式是根本不要讀取該文件。文件也有個迭代器會自動地在for循環,列表解析或者其餘迭代語句中對文件進行逐行讀取。
  • 內容是字符串,不是對象:注意從文件讀取的數據回到腳本時是一個字符串。若是字符串不是所須要的,就得將其轉換成其餘類型的對象。與print不一樣的是,當把數據寫入文件時,Python不會自動把對象轉換爲字符串——必須傳遞一個已經格式化的字符串。
  • close是一般選項:調用close方法將會終止對外部文件的鏈接。在Python中。一旦對象再也不被引用,則這個對象的內存空間就會自動被收回。當文件對象被收回的時候,Python也會自動關閉該文件。這就意味着不須要老是手動去關閉文件,尤爲是對於不會運行很長時間的簡單腳本,另外一方面,手動關閉調用沒有任何壞處,並且在大型程序中一般是個很不錯的習慣。嚴格的講,文件的這個手機完成後自動關閉的特性不是語言定義的一部分,並且可能隨時間而改變,所以,手動進行文件close方法調用是咱們須要養成的一個好習慣。
  • 文件是緩衝的而且是可查找的:關於關閉文件的提示很重要,由於關閉既釋放了操做系統資源也清空了緩衝區。默認狀況下,輸出文件老是緩衝的,這意味着寫入的文本可能不會當即自動從內存轉換到硬盤——關閉一個文件,或者運行其flush方法,迫使緩衝的數據進入硬盤。能夠有額外的open參數來避免緩存,可是,這可能會影響到性能。Python文件也是在字節偏移的基礎上隨機訪問的,他們的seek方法容許腳本跳轉到指定位置讀取或寫入。

簡單列子:首先爲輸出而打開一個新文件,寫入一個字符串(以終止符\n結束),以後關閉文件。接下來,咱們將會在輸入模式下再一次打開同一文件,讀取該行。注意第二個readline調用返回一個空字符串。這是Python文件方法告訴咱們已經到達文件底部(文件的空行是含有新行符的字符串,而不是空字符串):

>>> myfile = open('myfile.txt','w')
>>> myfile.write('hello textfile\n')
15
>>> myfile.write('goodbye text file\n')
18
>>> myfile.close()
>>> myfile = open('myfile.txt')
>>> myfile.readline()
'hello textfile\n'
>>> myfile.readline()
'goodbye text file\n'
>>> myfile.readline()
''
>>> open('myfile.txt').read()  #一次性所有讀取整個文件
'hello textfile\ngoodbye text file\n'
>>> print(open('myfile.txt').read()) #友好的顯示
hello textfile
goodbye text file
#若是想要一行一行地掃描一個文本文件,文件迭代器每每是最佳的選擇
>>> for line in open('myfile.txt'):
...     print(line,end='')
...
hello textfile
goodbye text file

python3.0+中文本和二進制文件

文件類型都有open的第二個參數決定,模式字符串包含一個「b」表示二進制。python老是支持文本和二進制文件。兩者之間的明顯區別:

  • 文本文件內容表示爲常規的str字符串,自動執行Unicode(包括ACSII和其餘的8位編碼)編碼和解碼,而且默認執行末行轉換。
  • 二進制文件把內容表示一個特殊的bytes字符串類型,而且容許程序不修改地訪問文件內容。
>>> data = open('data.bin','wb')
>>> data.write(b'\x00\x00\x00\x07spam\x00\x08')
10
>>> data.close()
>>> data = open('data.bin','rb').read()
>>> data
b'\x00\x00\x00\x07spam\x00\x08'
>>> data[4:8]
b'spam'
>>> data[4]
115
>>> bin(data[4])
'0b1110011'

此外,二進制文件不會對數據執行任何末行轉換;在根據轉化寫入和讀取並實現Unicode編碼的時候,文本文件默認地把全部形式和\n之間映射起來。

在文件中存儲並解析python對象

須要注意的是,咱們必須使用轉換工具把對象轉成字符串保存至文件中,寫入方法不會自動地替咱們作任何字符串格式轉換工做。

>>> x,y,z = 43,44,45
>>> s = 'spam' #字符串能夠直接存至文件
>>> D = {'a':1,'b':2}
>>> L = [1,2,3]
>>> F = open('datafile.txt','w')
>>> F.write(s + '\n') #添加換行符
5
>>> F.write('{0},{1},{2}\n'.format(x,y,z)) #須要轉換爲字符串
9
>>> F.write(str(L) + '$' + str(D) + '\n') #須要轉換爲字符串
27
>>> F.close()

經過打開和讀取文件查看內容返回的爲字符串。使用print語句則會解釋嵌行終止符顯示友好結果:

>>> chars = open('datafile.txt').read()
>>> chars
"spam\n43,44,45\n[1, 2, 3]${'b': 2, 'a': 1}\n"
>>> print(chars)
spam
43,44,45
[1, 2, 3]${'b': 2, 'a': 1}

在真正的使用用過程當中,讀取文件後python不會自動把字符串轉換爲數字或其餘類型的對象。咱們不得不使用其餘轉換工具,把文本文件中的字符串轉成真正的python對象。

>>> F = open('datafile.txt')
>>> line = F.readline()
>>> line
'spam\n'
>>> line.rstrip() #用rstrip方法去掉多餘的終止符
'spam'
>>> line
'spam\n'
>>> line[:-1]#或用分片去掉多餘的終止符
'spam'
>>> line = F.readline()
>>> line
'43,44,45\n'
>>> parts = line.split(',') #用split方法從逗號中轉換爲列表
>>> parts
['43', '44', '45\n']
>>> int(parts[1])
44
>>> parts = [int(p) for p in parts] #須要獲得真正的整數類型,須要int函數轉換
>>> parts
[43, 44, 45]
#還有一個方法能夠用內置函數eval進行轉換。eval函數可以把字符串當作可執行程序代碼(從技術上講,就是一個含有python表達式的字符串)。
>>> line = F.readline()
>>> line
"[1, 2, 3]${'b': 2, 'a': 1}\n"
>>> parts = line.split('$') #split從$中轉換爲列表
>>> parts
['[1, 2, 3]', "{'b': 2, 'a': 1}\n"]
>>> eval(parts[0]) #eval函數能夠把字符串轉換爲可執行代碼
[1, 2, 3]
>>> objects = [eval(p) for p in parts]
>>> objects
[[1, 2, 3], {'b': 2, 'a': 1}]

文件方法:

方法 描述
fileObject.close() close() 方法用於關閉一個已打開的文件。關閉後的文件不能再進行讀寫操做, 不然會觸發 ValueError 錯誤。 close() 方法容許調用屢次。當 file 對象,被引用到操做另一個文件時,Python 會自動關閉以前的 file 對象。 使用 close() 方法關閉文件是一個好的習慣。
fileObject.flush() flush() 方法是用來刷新緩衝區的,即將緩衝區中的數據馬上寫入文件,同時清空緩衝區,不須要是被動的等待輸出緩衝區寫入。通常狀況下,文件關閉後會自動刷新緩衝區,但有時你須要在關閉前刷新它,這時就可使用 flush() 方法。
fileObject.fileno()
fileno() 方法返回一個整型的文件描述符(file descriptor FD 整型),可用於底層操做系統的 I/O 操做。
fileObject.isatty()
isatty() 方法檢測文件是否鏈接到一個終端設備,若是是返回 True,不然返回 False。
fileObject.next()
next() 方法在文件使用迭代器時會使用到,在循環中,next()方法會在每次循環中調用,該方法返回文件的下一行,若是到達結尾(EOF),則觸發 StopIteration
fileObject.read([size])
read([size]) ,size爲數值,方法用於從文件讀取指定的字符數【無b模式時】或字節數【加上b模式時】,若是size未給定或爲負則讀取全部。
fileObject.readline()
readline() 方法用於從文件讀取整行,包括 "\n" 字符。若是指定了一個非負數的參數,則返回指定大小的字節數,包括 "\n" 字符。
fileObject.readlines( sizehint )
readlines() 方法用於讀取全部行(直到結束符 EOF)並返回列表,若給定sizeint>0,返回總和大約爲sizeint字節的行, 實際讀取值可能比sizhint較大, 由於須要填充緩衝區。若是碰到結束符 EOF 則返回空字符串。sizehint -- 從文件中讀取的字節數/字符數。
fileObject.seek(offset[, whence])
seek() 方法用於移動文件讀取指針到指定位置。offset -- 開始的偏移量,也就是表明須要移動偏移的字節數。whence:可選,默認值爲 0。給offset參數一個定義,表示要從哪一個位置開始偏移;0表明從文件開頭開始算起,1表明從當前位置開始算起,2表明從文件末尾算起。
fileObject.tell(offset[, whence])
tell() 方法返回文件的當前位置,即文件指針當前位置。
fileObject.truncate( [ size ])
truncate() 方法用於截斷文件,若是指定了可選參數 size,則表示截斷文件爲 size 個字符。 若是沒有指定 size,則從當前位置起截斷;截斷以後 size 後面的全部字符被刪除。size -- 可選,若是存在則文件截斷爲 size 字節。
fileObject.write( [ str ])
write() 方法用於向文件中寫入指定字符串。在文件關閉前或緩衝區刷新前,字符串內容存儲在緩衝區中,這時你在文件中是看不到寫入的內容的。str -- 要寫入文件的字符串。
fileObject.writelines( [ str ])
writelines() 方法用於向文件中寫入一序列的字符串。這一序列字符串能夠是由迭代對象產生的,如一個字符串列表。換行須要制定換行符 \n。str -- 要寫入文件的字符串序列。

 

 

用pickle存儲Python的原生對象

使用eval能夠把字符串轉換爲對象,它是一個功能強大的工具,有時它太過於強大,只要權限足夠,會執行python的任何表達式,甚至有可能會刪除計算機上的全部文件的表達式。

若是真的要存儲python原生對象,又沒法信賴文件的數據來源,python標準庫pickle模塊會是個理想的選擇。

pickle模塊幾乎可以存儲任何python對象的高級工具,不用咱們把字符串轉換來轉換去,也就是咱們能夠直接存儲任何對象,從文件中取回時,仍然是以前保存時的對象。實際上,pickle是內部將對像轉換爲字符串形式,取回時pick自動重建對象。

>>> D = {'a':1,'b':2}
>>> F = open('datafile.pkl','wb')
>>> import pickle
>>> pickle.dump(D,F)
>>> F.close()
>>> F = open('datafile.pkl','rb')
>>> E = pickle.load(F)
>>> E
{'b': 2, 'a': 1}

注意:pickle程序建立和使用一個bytes字符串對象,意味着這些對象建立的是二進制模式文件。因此咱們以二進制模式打開用來存儲pickle化的對象的文件。

文件中打包位二進制數據的存儲與解析

有些高級應用程序須要處理打包的二進制數據,這些數據多是C語言程序生成的。Python標準庫中包含一個可以在一範圍起做用的工具:struct模塊可以構造並解析打包的二進制數據。從某種意義上說,它是另外一個數據轉換工具,可以把文件中的字符串讀爲二進制數據。

例如:要生成一個打包的二進制數據文件,用‘wb’(寫入二進制)模式打開,並將一個格式化字符串和幾個python對象傳給struct。這裏用的格式化字符串是指一個4字節整數、一個包含4個字符的字符串以及一個2位整數的數據包,全部這些都按照高位在前(big-endian)的形式(其餘格式代碼可以處理補位字節、浮點數)。

##struct打包
>>> F = open('data.bin','wb')
>>> import struct
>>> data = struct.pack('>i4sh',7,b'spam',8) #注意字符串必須是二進制b模式
>>> data
b'\x00\x00\x00\x07spam\x00\x08'
>>> F.write(data)
10
>>> F.close()

##struct解包
>>> F = open('data.bin','rb')
>>> data = F.read()
>>> data
b'\x00\x00\x00\x07spam\x00\x08'
>>> values = struct.unpack('>i4sh',data)
>>> values
(7, b'spam', 8)

詳情能夠參考python庫手冊,或交互模式下dir和help函數查看

>>> dir(struct)
['Struct', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__lo
ader__', '__name__', '__package__', '__spec__', '_clearcache', 'calcsize', 'erro
r', 'iter_unpack', 'pack', 'pack_into', 'unpack', 'unpack_from']

文件上下文管理器

文件上下文管理比文件自身多了一個異常處理功能,它容許咱們把文件處理代碼包裝到一個邏輯層中,以確保在退出後能夠自動關閉文件,而不是依賴於垃圾收集上的自動關閉:

with open(r'c:\misc\data.txt') as fp:
    for line1 in fp:
        "...use line here..."

python2.7及之後版本,還能夠同時打開多個文件:

with open(r'c:\misc\data1.txt') as fp1 , open(r"c:\misc\data1.txt") as fp2,.....:
    for line1 in fp1:
        "...use line here..."
    for line2 in fp2:
        "...use line here..."

其餘文件類工具

open函數可以實如今Python中編寫的絕大多數文件處理。儘管更高級的任務,Python還有額外的類文件工具:管道、先進先出隊列(FIFO)、套接字、經過鍵訪問文件、對象持久、基於描述符的文件、關係數據庫和麪向對象數據庫接口等。例如,描述符文件(descriptor file) 支持文件鎖定和其餘的底層工具,而套接字提供網絡和進程間通訊的接口。

  • 標準流:在sys模塊中預先打開的文件對象,例如:sys.stout
  • os模塊中的描述文件:處理整數文件,支持諸如文件鎖定之類的較低級工具。
  • socket、pipes和FIFO文件:文件類對象,用於同步進程或者經過網絡進行通訊。
  • 經過鍵來存取的文件:經過鍵直接存儲的不變的python對象。
  • shell命令流:像os.popen和subprocess.Popen這樣的工具,支持產生shell命令,並讀取和寫入到標準流。

 

檢查代碼對象類型

Python腳本中至少有3種方法能夠作到代碼對象類型檢測:

>>> if type(L) == type([]): print('yes')
...
yes
>>> if type(L) == list: print('yes')
...
yes
>>> if isinstance(L,list): print('yes')
...
yes
相關文章
相關標籤/搜索