文章目錄
- 1 迭代器與生成器
- 1.1 迭代器
- 1.1.1 基本使用
- 1.1.2 手動迭代(帶異常處理)
- 1.1.3 自定義迭代器
- 1.2 生成器
- 1.2.1 工作原理
- 1.2.2 斐波那契數列示例
- 1.3 推導式
- 1.3.1 列表推導式
- 1.3.2 字典推導式
- 1.3.3 集合推導式
- 1.4.4 元組推導式(生成器表達式)
- 2 with關鍵字
- 2.1 基本語法
- 2.2 常用場景
- 2.2.1 文件操作(最典型)
- 2.2.2 數據庫連接
- 2.2.3 線程鎖
- 2.3 工作原理:上下文管理協議
- 2.4 自定義上下文管理器
- 2.4.1 方式 1:類實現
- 2.4.2 方式 2:使用 contextlib 模塊
- 2.5 最佳實踐
1 迭代器與生成器
1.1 迭代器
- 迭代器是可記住遍歷位置的對象
- 只能向前遍歷,不能后退
- 核心方法:
iter()
創建迭代器,next()
獲取下一個元素
1.1.1 基本使用
# 創建迭代器
list = [1, 2, 3, 4]
it = iter(list) # 創建迭代器對象# 訪問元素
print(next(it)) # 1
print(next(it)) # 2# 使用for循環遍歷
for x in it:print(x, end=" ") # 3 4
1.1.2 手動迭代(帶異常處理)
import sysit = iter([1, 2, 3, 4])while True:try:print(next(it))except StopIteration:sys.exit() # 迭代結束時退出
1.1.3 自定義迭代器
需實現兩個方法:
__iter__()
: 返回迭代器對象本身__next__()
: 返回下一個元素,迭代結束時拋出StopIteration
class MyNumbers:def __iter__(self):self.a = 1return selfdef __next__(self):if self.a <= 20: # 限制迭代次數x = self.aself.a += 1return xelse:raise StopIteration # 結束迭代# 使用自定義迭代器
myclass = MyNumbers()
for x in iter(myclass):print(x) # 輸出1到20
1.2 生成器
- 使用
yield
關鍵字的函數稱為生成器 - 生成器是特殊的迭代器,可逐步產生值
- 調用生成器函數返回的是迭代器對象
1.2.1 工作原理
- 執行到
yield
時返回值并暫停 - 下次調用時從暫停處繼續執行
- 適合處理大量數據或無限序列
def countdown(n):while n > 0:yield n # 返回當前值并暫停n -= 1# 使用生成器
generator = countdown(5)
print(next(generator)) # 5
print(next(generator)) # 4# 用for循環迭代剩余值
for value in generator:print(value) # 3 2 1
1.2.2 斐波那契數列示例
def fibonacci(n):a, b, counter = 0, 1, 0while True:if counter > n:returnyield a # 返回當前斐波那契數a, b = b, a + bcounter += 1# 使用生成器
f = fibonacci(10)
for x in f:print(x, end=" ") # 0 1 1 2 3 5 8 13 21 34 55
1.3 推導式
推導式是一種簡潔的數據處理語法,可從一個序列構建新序列,支持列表、字典、集合和元組。
1.3.1 列表推導式
格式:[表達式 for 變量 in 列表 if 條件]
實例 1:過濾并轉換
names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
new_names = [name.upper() for name in names if len(name) > 3]
# 結果: ['ALICE', 'JERRY', 'WENDY', 'SMITH']
實例 2:數值篩選
multiples = [i for i in range(30) if i % 3 == 0]
# 結果: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
1.3.2 字典推導式
格式:{key表達式: value表達式 for 變量 in 集合 if 條件}
實例 1:字符串長度字典
listdemo = ['Google','Runoob', 'Taobao']
newdict = {key: len(key) for key in listdemo}
# 結果: {'Google': 6, 'Runoob': 6, 'Taobao': 6}
實例 2:數字平方字典
dic = {x: x**2 for x in (2, 4, 6)}
# 結果: {2: 4, 4: 16, 6: 36}
1.3.3 集合推導式
格式:{表達式 for 變量 in 序列 if 條件}
實例 1:計算平方
setnew = {i**2 for i in (1, 2, 3)}
# 結果: {1, 4, 9}
實例 2:字符篩選
a = {x for x in 'abracadabra' if x not in 'abc'}
# 結果: {'d', 'r'}
1.4.4 元組推導式(生成器表達式)
格式:(表達式 for 變量 in 序列 if 條件)
注意:返回生成器對象,需用tuple()
轉換
實例:生成數字元組
a = (x for x in range(1, 10)) # 生成器對象
print(tuple(a)) # 轉換為元組
# 結果: (1, 2, 3, 4, 5, 6, 7, 8, 9)
2 with關鍵字
with
關鍵字用于上下文管理,簡化資源(如文件、數據庫連接)的獲取與釋放,確保資源使用后被正確清理。
對比傳統資源管理方式:
傳統方式(try-finally) | with 語句 |
---|---|
需手動調用 close() | 自動釋放資源 |
代碼冗長 | 簡潔直觀 |
易遺漏關閉操作 | 異常安全 |
傳統文件操作示例:
file = open('test.txt', 'r')
try:content = file.read()
finally:file.close() # 必須手動關閉
2.1 基本語法
with 表達式 [as 變量]:# 代碼塊(使用資源)
- 表達式返回上下文管理器對象
as 變量
:可選,將對象賦值給變量- 代碼塊執行完畢后,自動觸發資源清理
2.2 常用場景
2.2.1 文件操作(最典型)
# 讀取文件
with open('example.txt', 'r') as file:content = file.read()print(content)
# 退出代碼塊后,文件自動關閉# 同時操作多個文件
with open('in.txt', 'r') as infile, open('out.txt', 'w') as outfile:outfile.write(infile.read().upper()) # 轉換為大寫并寫入
2.2.2 數據庫連接
import sqlite3with sqlite3.connect('mydb.db') as conn:cursor = conn.cursor()cursor.execute('SELECT * FROM users')print(cursor.fetchall())
# 連接自動關閉,無需手動調用 close()
2.2.3 線程鎖
import threadinglock = threading.Lock()with lock:# 臨界區代碼(自動加鎖/解鎖)print("線程安全的操作")
2.3 工作原理:上下文管理協議
支持 with
的對象需實現兩個方法:
__enter__()
:進入上下文時調用,返回值賦給as
后的變量__exit__()
:退出上下文時調用,負責資源清理
執行流程:
- 執行表達式,獲取上下文管理器
- 調用
__enter__()
方法,進入上下文 - 執行代碼塊
- 無論是否發生異常,都調用
__exit__()
方法
異常處理機制
__exit__()
方法接收三個參數:exc_type
(異常類型)、exc_val
(異常值)、exc_tb
(追蹤信息)
- 返回
True
:表示異常已處理,不再傳播 - 返回
False
/None
:異常繼續向外傳播
2.4 自定義上下文管理器
2.4.1 方式 1:類實現
class Timer:def __enter__(self):import timeself.start = time.time()return self # 可通過 as 接收def __exit__(self, exc_type, exc_val, exc_tb):import timeprint(f"耗時: {time.time() - self.start:.2f}秒")return False # 不抑制異常# 使用
with Timer() as t:sum(range(10000000)) # 執行耗時操作
2.4.2 方式 2:使用 contextlib 模塊
from contextlib import contextmanager@contextmanager
def tag(name):print(f"<{name}>") # __enter__ 部分yield # 暫停,執行代碼塊print(f"</{name}>") # __exit__ 部分# 使用
with tag("h1"):print("這是標題內容")# 輸出:
# <h1>
# 這是標題內容
# </h1>
2.5 最佳實踐
- 優先使用 with:處理文件、網絡連接、鎖等資源時,必用
with
- 精簡代碼塊:
with
內只寫與資源相關的操作 - 多資源管理:一個
with
可同時管理多個資源(用逗號分隔) - 異常處理:自定義上下文時,明確是否需要抑制異常
with
語句通過自動化資源管理,大幅提升了代碼的可讀性和可靠性,是 Python 中處理資源的首選方式。