1. 程式人生 > >讀書筆記:LearningPython第五版 (第九章 Tuples, Files, and Everything Else)

讀書筆記:LearningPython第五版 (第九章 Tuples, Files, and Everything Else)

重點:

  1. tuple的操作
  2. collections模組中有其他的多功能型別
  3. 檔案操作
  4. 檔案本身是有buffer的,而且二進位制操作可以定址seek
  5. 文字檔案最好的讀取方式是直接迭代
  6. 檔案的文字處理會自動使用utf-8轉換編碼而且對文字處理會自動使用utf-8轉換編碼
  7. 物件拷貝的方法: 4種
  8. Python內建物件的比較規則
  9. Python內建物件的比較,是遞迴的
  10. Python物件都是有TrueFalse
  11. None本身時一個特殊物件,是一個實際記憶體空間,Python內建的特殊的名稱

Chap9 Tuples, Files, and Everything Else

9.1 Tuple

Operation Interpretation
() An empty tuple
T = (0,) A one-item tuple (not an expression)
T = (0, ‘Ni’, 1.2, 3) A four-item tuple
T = 0, ‘Ni’, 1.2, 3 Python允許省略括號
T = (‘Bob’, (‘dev’, ‘mgr’)) Nested tuples
T = tuple(‘spam’) Tuple of items in an iterable
T[i] Index, index of index, slice, length
T[i][j]
T[i:j]
len(T)
T1 + T2 Concatenate, repeat
T * 3
for x in T: print(x) Iteration
‘spam’ in T membership
[x ** 2 for x in T]
T.index(‘Ni’) Methods in 2.6, 2.7, and 3.X: search, count
T.count(‘Ni’)
namedtuple(‘Emp’, [‘name’, ‘jobs’]) Named tuple extension type

9.2 Named Tuples

>>> from collections import namedtuple # Import extension type
>>> Rec = namedtuple('Rec', ['name', 'age', 'jobs']) # Make a generated class
>>> bob = Rec('Bob', age=40.5, jobs=['dev', 'mgr']) # A named-tuple record
>>> bob
Rec(name='Bob', age=40.5, jobs=['dev', 'mgr'])

>>> bob[0], bob[2] # Access by position
('Bob', ['dev', 'mgr'])
>>> bob.name, bob.jobs # Access by attribute
('Bob', ['dev', 'mgr'])

# 改變成 OrderedDict型別
>>> O = bob._asdict() # Dictionary-like form
>>> O['name'], O['jobs'] # Access by key too
('Bob', ['dev', 'mgr'])
>>> O
OrderedDict([('name', 'Bob'), ('age', 40.5), ('jobs', ['dev', 'mgr'])])

# Tuple Unpacking
name, age, jobs = bob

9.3 File

Operation Interpretation
output = open(r’C:\spam’, ‘w’)
input = open(‘data’, ‘r’) Create input file (‘r’ means read)
input = open(‘data’) Same as prior line (‘r’ is the default)
aString = input.read() Read entire file into a single string
aString = input.read(N) Read up to next N characters (or bytes) into a string
aString = input.readline() Read next line (including \n newline) into a string
aList = input.readlines() Read entire file into list of line strings (with \n)
output.write(aString) Write a string of characters (or bytes) into file
output.writelines(aList) Write all line strings in a list into file
output.close() Manual close (done for you when file is collected)
output.flush() Flush output buffer to disk without closing
anyFile.seek(N) Change file position to offset N for next operation
for line in open(‘data’): use line File iterators read line by line
open(‘f.txt’, encoding=‘latin-1’) Python 3.X Unicode text files (str strings)
open(‘f.bin’, ‘rb’) Python 3.X bytes files (bytes strings)
codecs.open(‘f.txt’, encoding=‘utf8’) Python 2.X Unicode text files (unicode strings)
open(‘f.bin’, ‘rb’) Python 2.X bytes files (str strings)

file本身是個iterator

9.3.1 open函式

引數

open(filename, mode, [buffer, encoding] )
  1. filename 檔名
  2. mode: 2.1. w:寫 2.2. r:讀 2.3. a:追加 2.4. b:二進位制 2.5. +可讀可寫,常常配合 seek
  3. buffer: 0代表不buffer,直接寫入disk

9.3.2 使用file

  1. 最優的讀取方法是將file物件當作 iterator來遍歷
  2. file是有快取的 buffered: flush(),而且二進位制的檔案是可定址的seekable: seek()
  3. readline方法當讀到檔案尾部的時候,會返回空字串;區別於空行——空行會返回\n
  4. write()函式會返回寫入的字元個數
  5. close函式在CPython中是可選的,因為有垃圾回收,它會回收資源的同時順便關閉file。但是推薦寫上
  6. Python對文字檔案會自動使用Unicode進行轉碼和編碼,並且自動轉換換行符
  7. 對檔案的write需要自己格式化,它不會幫你呼叫str方法。

eval 函式可以 將字串當作python程式執行: eval("COMMAND")

9.3.3 Pickle

物件序列化模組

# 寫入檔案
>>> D = {'a': 1, 'b': 2}
>>> F = open('datafile.pkl', 'wb')
>>> import pickle
>>> pickle.dump(D, F) # Pickle any object to file
>>> F.close()在這裡插入程式碼片

# 從檔案讀取
>>> F = open('datafile.pkl', 'rb')
>>> E = pickle.load(F) # Load any object from file
>>> E
{'a': 1, 'b': 2}

shelve模組是基於pickle,使用key來獲取物件的序列化模組

9.3.4 json

json支援的物件型別不如pickle多

# 字串
>>> import json
>>> S = json.dumps(rec)
>>> O = json.loads(S)

# 檔案讀寫
>>> json.dump(rec, fp=open('testjson.txt', 'w'), indent=4)
>>> P = json.load(open('testjson.txt'))

9.3.5 struct

構造和解析二進位制

>>> F = open('data.bin', 'wb') # Open binary output file
>>> import struct
>>> data = struct.pack('>i4sh', 7, b'spam', 8) # Make packed binary data
>>> data
b'\x00\x00\x00\x07spam\x00\x08'
>>> F.write(data) # Write byte string
>>> F.close()

9.3.6 其他file工具

  1. 標準流,比如 sys.out
  2. os模組內的file descriptor
  3. Sockets, pipes, and FIFOs
  4. 使用key來訪問序列化物件的shelves
  5. Shell command streams: subprocess.Popen,os.popen

9.4 核心Python型別回顧

Object type Category Mutable?
Numbers (all) Numeric No
Strings (all) Sequence No
Lists Sequence Yes
Dictionaries Mapping Yes
Tuples Sequence No
Files Extension N/A
Sets Set Yes
Frozenset Set No
bytearray Sequence Yes

9.4.1 引用複製問題

要注意引用的問題,如果為了防止被改變,要先copy。 而切片和copy方法不會深度複製,所以要用copy.deepcopy方法

  1. 切片可以返回copy : 注意:只返回上層的copy,而不是深拷貝
  2. 字典、list、set有自己的copy方法, 注意:也不是深拷貝
  3. 內建函式可以建立新物件:list(L), dict(D), set(S)
  4. copy模組的方法:copy, deepcopy

9.4.2 比較相等

python的核心物件是使用的遞迴比較,從最上層開始,直到比較出結果

>>> L1 = [1, ('a', 3)] # Same value, unique objects
>>> L2 = [1, ('a', 3)]
>>> L1 == L2, L1 is L2 # Equivalent? Same object?
(True, False)


# 小字串會快取
>>> S1 = 'spam'
>>> S2 = 'spam'
>>> S1 == S2, S1 is S2
(True, True)

# 長一點就不會了
>>> S1 = 'a longer string'
>>> S2 = 'a longer string'
>>> S1 == S2, S1 is S2
(True, False)

巢狀的比較:

>>> L1 = [1, ('a', 3)]
>>> L2 = [1, ('a', 2)]
>>> L1 < L2,      L1 == L2,      L1 > L2 # Less, equal, greater: tuple of results
(False, False, True)

Python核心型別比較方法

  1. 數字型別是經過轉換成最大相容型別後,按照數字大小比較
  2. 字串是一個字元一個字元,根據編碼數字大小比較(ord函式返回數字)
  3. lits和tuple是從左到右一個一個比較元素,而且如果有巢狀,會遞迴進去比較
  4. sets相等的情況是包含同樣的元素
  5. 字典相等的情況是它們 sorted (key, value)全部一致
  6. 型別不同的物件不支援magnitude比較: 11 > "11" # 報錯; 11 == "11" #False

9.5 Python的bool型別

Python中的每個物件內在都有True和False:

  1. Numbers are false if zero, and true otherwise.
  2. Other objects are false if empty, and true otherwise.
Object Value
“spam” True
“” False
" " True
[1, 2] True
[] False
{‘a’: 1} True
{} False
1 True
0.0 False
None False

None不代表沒有,或者未定義, None是一個真正的物件,一個真正的記憶體,是Python內建的一個特殊名字。

9.6 Type物件

型別本身是type型別, dict, list, str, tuple, int, float, complex, bytes, type, set, file 這些都是構造方法,不算是型別轉換,但是可以看成是這樣。

types模組還有更多關於type的tool。

type([1]) == type([])       # Compare to type of another list
type([1]) == list       # Compare to list type name
isinstance([1], list)      # Test if list or customization thereof
import types            # types has names for other types
def f(): pass

在這裡插入圖片描述type(f) == types.FunctionType

9.7 其他注意點

  1. Repetition Adds One Level Deep
>>> L = [4, 5, 6]
>>> X = L * 4 # Like [4, 5, 6] + [4, 5, 6] + ...
>>> Y = [L] * 4 # [L] + [L] + ... = [L, L,...]
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 5, 6], [4, 5, 6], [4, 5, 6], [4, 5, 6]]


# Y內的每個元素都是L的引用,所以它們是一個物件
>>> L[1] = 0 # Impacts Y but not X
>>> X
[4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6]
>>> Y
[[4, 0, 6], [4, 0, 6], [4, 0, 6], [4, 0, 6]]
  1. Beware of Cyclic Data Structures 防止迴圈引用自己

Python會把迴圈引用,列印成[...]

>>> L = ['grail'] # Append reference to same object
>>> L.append(L) # Generates cycle in object: [...]
>>> L
['grail', [...]]