python 基础

[文章目录]

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)

发表评论

邮箱地址不会被公开。 必填项已用*标注