try-except-finally
try:
execution block ##正常执行模块
except A:
exc A block ##发生A错误时执行
except B:
exc B block ##发生B错误时执行
except:
other block ##发生除了A,B错误以外的其他错误时执行
else:
if no exception, jump to here ##没有错误时执行
finally:
final block ##总是执行
上下文管理器
上下文管理器是指符合上下文协议的一个类(类中实现了__enter__
方法和__exit__
方法)。即可以在一段代码执行前,先执行__enter__
中的代码用于预处理,执行完这段代码之后再执行__exit__
中的代码进行清理工作。比如入栈、出栈,打开数据库、关闭数据库,打开文件、关闭文件等操作都可以用上下文管理器来完成。
with ... as
with expression [as variable]:
with-block
首先执行expression返回的上下文管理器实例里面的__enter__
函数,它的返回值会赋给as后面的variable,想让它返回什么就返回什么,只要你知道怎么处理就可以了,如果不写as variable,返回值会被忽略。
然后,开始执行with-block中的语句,不论成功失败(比如发生异常、错误,设置sys.exit()),在with-block执行完成后,会执行expression中的__exit__
函数。
当with...as语句中with-block被执行或者终止后,这个类对象应该做什么。如果这个码块执行成功,则exception_type,exception_val, trace的输入值都是null。如果码块出错了,就会变成像try/except/finally语句一样,exception_type, exception_val, trace 这三个值系统会分配值。
这三个值可以在__exit__
函数中使用,比如可以打印错误信息。
等价于
try:
执行 __enter__的内容
执行 with_block.
finally:
执行 __exit__内容
原文链接:https://blog.csdn.net/qiqicos/article/details/79200089
@contextmanager
通过contextlib模块下提供的@contextmanager装饰器,能够更方便的将一个普通类变成上下文管理器。
@contextmanager通过将一个函数变成生成器的方式来为普通类添加进入和退出时的处理代码,从而实现了将普通类变成一个上下文管理器。
from contextlib import contextmanager
@contextmanager
def patch_model(
model: torch.nn.Module,
tp_group: GroupCoordinator,
):
backup_ca_comm = tp_group.ca_comm
yield model.forward
tp_group.ca_comm = backup_ca_comm
with patch_model(
self.model_runner.model,
tp_group=self.model_runner.tp_group,
) as forward:
self.capture_one_batch_size(forward)
执行流程:①with语句调用patch_model函数=>②执行patch_model中yield之前的代码(backup)=>③执行yield语句中的代码(model.forward)=>④执行with语句中的代码(self.capture_one_batch_size(forward))=>⑤执行yield语句后的代码(restore tp_group)
with语句后是调用被修饰的函数,而不是实例化上下文管理器对象
as forward的forward是yield语句的返回值,上述示例中model.forward
yield前、中、后的代码都可以省略不写
@dataclass
dataclass 提供一个简便的方式创建数据类, 默认实现init(), repr(), eq()方法.
dataclass 可以认为是提供了一个简写__init__
方法的语法糖. 类型注释是必填项 (不限制数据类型时, 添加typing.Any为类型注释), 默认值的传递方式和__init__
方法的参数格式一致.
from dataclasses import dataclass
@dataclass
class Player:
name: str
number: int
position: str
age: int
grade: str
james = Player('Lebron James', 23, 'SF', 25, 'S')
> james
> Player(name='Lebron James', number=23, position='SF', age=25, grade='S')
数据类可以嵌套为其他数据类的字段
Field 对象是用于描述定义的字段的,比如字段是否加载到 __init__
里面去,自定义处理的参数等。比如:
def value():
return "123"
@dataclass
class A:
a: str = field(default_factory=value)