讀書筆記:LearningPython第五版 (第九章 Tuples, Files, and Everything Else)
阿新 • • 發佈:2018-12-13
重點:
- tuple的操作
collections
模組中有其他的多功能型別- 檔案操作
- 檔案本身是有
buffer
的,而且二進位制操作可以定址seek
- 文字檔案最好的讀取方式是直接迭代
- 檔案的文字處理會自動使用
utf-8
轉換編碼而且對文字處理會自動使用utf-8
轉換編碼 - 物件拷貝的方法: 4種
- Python內建物件的比較規則
- Python內建物件的比較,是遞迴的
- Python物件都是有
True
和False
的 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] )
- filename 檔名
- mode:
2.1.
w
:寫 2.2.r
:讀 2.3.a
:追加 2.4.b
:二進位制 2.5.+
:可讀可寫,常常配合seek
- buffer: 0代表不buffer,直接寫入disk
9.3.2 使用file
- 最優的讀取方法是將file物件當作 iterator來遍歷
- file是有快取的
buffered
:flush()
,而且二進位制的檔案是可定址的seekable
: seek() readline
方法當讀到檔案尾部的時候,會返回空字串;區別於空行——空行會返回\n
write()
函式會返回寫入的字元個數close
函式在CPython中是可選的,因為有垃圾回收,它會回收資源的同時順便關閉file。但是推薦寫上- Python對文字檔案會自動使用
Unicode
進行轉碼和編碼,並且自動轉換換行符 - 對檔案的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工具
- 標準流,比如
sys.out
- os模組內的file descriptor
- Sockets, pipes, and FIFOs
- 使用key來訪問序列化物件的
shelves
- 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
方法
- 切片可以返回copy : 注意:只返回上層的copy,而不是深拷貝
- 字典、list、set有自己的
copy
方法, 注意:也不是深拷貝 - 內建函式可以建立新物件:
list(L), dict(D), set(S)
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核心型別比較方法
- 數字型別是經過轉換成最大相容型別後,按照數字大小比較
- 字串是一個字元一個字元,根據編碼數字大小比較(
ord
函式返回數字) lits和tuple
是從左到右一個一個比較元素,而且如果有巢狀,會遞迴進去比較sets
相等的情況是包含同樣的元素- 字典相等的情況是它們
sorted (key, value)
全部一致 - 型別不同的物件不支援
magnitude
比較:11 > "11" # 報錯; 11 == "11" #False
9.5 Python的bool型別
Python中的每個物件內在都有True和False:
- Numbers are false if zero, and true otherwise.
- 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 其他注意點
- 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]]
- Beware of Cyclic Data Structures 防止迴圈引用自己
Python會把迴圈引用,列印成[...]
>>> L = ['grail'] # Append reference to same object
>>> L.append(L) # Generates cycle in object: [...]
>>> L
['grail', [...]]