读书笔记:LearningPython第五版 (★第九章 Tuples, Files, and Everything Else)

本文深入探讨Python中的数据结构如元组、命名元组,以及文件操作的基础知识,包括打开、读取、写入文件的方法,同时介绍了Pickle、json和struct模块在数据序列化中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

重点:

  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

OperationInterpretation
()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, 3Python允许省略括号
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 + T2Concatenate, repeat
T * 3
for x in T: print(x)Iteration
‘spam’ in Tmembership
[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

OperationInterpretation
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 typeCategoryMutable?
Numbers (all)NumericNo
Strings (all)SequenceNo
ListsSequenceYes
DictionariesMappingYes
TuplesSequenceNo
FilesExtensionN/A
SetsSetYes
FrozensetSetNo
bytearraySequenceYes

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.
ObjectValue
“spam”True
“”False
" "True
[1, 2]True
[]False
{‘a’: 1}True
{}False
1True
0.0False
NoneFalse

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', [...]]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值