用法一:文件
如果不使用with,我们应该如何打开一个文件?
1 2 3 4 5 6 7 8 9 10
| try: f = open('a.txt', 'r', encoding="utf-8") print(f.read()) finally: if f: 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() 搭配,节省资源 + 提速。