用法一:文件

如果不使用with,我们应该如何打开一个文件?

1
2
3
4
5
6
7
8
9
10
try:
# 1. [进入]
f = open('a.txt', 'r', encoding="utf-8")
# 2. [执行]
print(f.read())
finally:
if f:
# 3. [退出]
f.close()

with在这里就起到一个封装try和finally的作用,finally的作用就是如果文件在io过程中产生了错误,也能正常执行f.close()安全关闭文件

写成with语句

1
2
with open("a.txt", "r", encoding="utf-8") as f:
print(f.read())

即把open(“a.txt”, “r”, encoding=”utf-8”)的结果命名为f,再执行print(f.read())的语句块。

用法二:pytorch梯度管理

with语句可以临时切换计算环境状态并自动恢复初始状态。由于在验证和测试的过程中都不需要积累梯度,模型切换到eval模式使用torch.no_grad(),说明临时切换到了禁用张量的自动梯度计算模式,在计算结束后会恢复到计算梯度的状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
model.train()
train_loss = 0.0
val_loss = 0.0
for data in trainloader:
optimizer.zero_grad()
x, target = data[0].to(device),data[1].to(device)
pred = model(x)
bat_loss = loss(pred,target,model)
optimizer.step()
train_loss += bat_loss.detach().cpu().item()
plt_train_loss.append(train_loss/trainloader.dataset.__len__())





# 切换到验证模式
model.eval()
with torch.no_grad():
for data in valloader:
val_x, val_target = data[0].to(device), data[1].to(device)
val_pred = model(val_x)
val_bat_loss = loss(val_pred,val_target,model)
val_loss += val_bat_loss.detach().cpu().item()
if val_loss < min_val_loss:
torch.save(model, save_)
plt_val_loss.append(val_loss/valloader.dataset.__len__())

总结:

with 语句核心:Python 上下文管理器语法糖,自动初始化 + 自动收尾,异常安全。

两大核心用法:

文件操作:with open(…) as f
自动打开 / 关闭文件,避免句柄泄露,替代繁琐的 try…finally。

PyTorch 梯度管理:with torch.no_grad()
验证 / 测试阶段临时禁用梯度计算,自动恢复状态,需与 model.eval() 搭配,节省资源 + 提速。