python关于__ enter__和__exit__方法,with语句

1.上下文管理协议

A context manager is an object that defines the runtime context to be established when executing a with statement. The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the block of code. Context managers are normally invoked using the with statement (described in section The with statement), but can also be used by directly invoking their methods.
Typical uses of context managers include saving and restoring various kinds of global state, locking and unlocking resources, closing opened files, etc.
上下文管理器是一个对象,它定义在执行with语句时要建立的运行时上下文。 上下文管理器处理进入和退出所需运行时上下文以执行代码块。 通常使用with语句调用上下文管理器(在with语句一节中描述),但也可以通过直接调用它们的方法来使用。
上下文管理器的典型用途包括保存和恢复各种全局状态,锁定和解锁资源,关闭打开的文件等。

上下文管理器是用来定义执行with语句时建立的运行时上下文的一个对象,通过调用对象的__ enter__和__ exit__ 方法来实现

2.__ enter__()

object.__ enter__(self)
Enter the runtime context related to this object. The with statement will bind this method’s return value to the target(s) specified in the as clause of the statement, if any.
进入对象的运行时上下文,with语句会把这个方法的返回值赋给as指定的变量.

3.__ exit__

object.__ exit__(self, exc_type, exc_value, traceback)
Exit the runtime context related to this object. The parameters describe the exception that caused the context to be exited. If the context was exited without an exception, all three arguments will be None.
If an exception is supplied, and the method wishes to suppress the exception (i.e., prevent it from being propagated), it should return a true value. Otherwise, the exception will be processed normally upon exit from this method.
Note that __ exit__() methods should not reraise the passed-in exception; this is the caller’s responsibility.

退出对象的运行时上下文,参数描述了导致上下文退出的异常信息.当正常退出时,三个参数都为None, 如果异常发生,则参数记录异常信息:exc_type(异常类型), exc_value(异常信息), traceback(异常追踪).
如果希望exit阻止异常报出, 那应该返回True(返回True则正常执行with后面的语句). 否则exit运行结束后会正常抛出异常信息.
注意,exit方法不应该重新抛出被传入的异常, 这是调用者的责任(?)

使用示例:

class Context:
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print('enter running')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit running')
        print(exit, exc_type, exc_val, exc_tb, sep='\n')

with Context('sabi') as t:
    print(t.name)
    print(t.__dict__)

print('hhahahah')

#result
enter running
sabi
{'name': 'sabi'}
exit running
Use exit() or Ctrl-Z plus Return to exit
None
None
None
hhahahah

4.with语句

The with statement is used to wrap the execution of a block with methods defined by a context manager (see section With Statement Context Managers). This allows common try…except…finally usage patterns to be encapsulated for convenient reuse.

with语句利用上下文管理器来包装要执行的语句块, 这样可以将try,except等使用模式封装起来以便重用.

with语句执行流程:

The execution of the with statement with one “item” proceeds as follows:
1.The context expression (the expression given in the with_item) is evaluated to obtain a context manager.
评估上下文表达式以获得上下文管理器

2.The context manager’s __ exit__() is loaded for later use.

3.The context manager’s __ enter__() method is invoked.

4.If a target was included in the with statement, the return value from __ enter__() is assigned to it.
Note:
The with statement guarantees that if the __ enter__() method returns without an error, then __ exit__() will always be called. Thus, if an error occurs during the assignment to the target list, it will be treated the same as an error occurring within the suite would be. See step 6 below.
注意:enter的返回结果赋值给with指定的变量时出错, 则视为在执行with下的语句块时出错,exit依然会触发.

5.The suite is executed.

6.The context manager’s __ exit__() method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __ exit__(). Otherwise, three None arguments are supplied.
If the suite was exited due to an exception, and the return value from the __ exit__() method was false, the exception is reraised. If the return value was true, the exception is suppressed, and execution continues with the statement following the with statement.
If the suite was exited for any reason other than an exception, the return value from __ exit__() is ignored, and execution proceeds at the normal location for the kind of exit that was taken.

4.2多个with叠加
With more than one item, the context managers are processed as if multiple with statements were nested:

with A() as a, B() as b:
    suite

# is equivalent to

with A() as a:
    with B() as b:
        suite
`__enter__`和`__exit__`是Python中用于上下文管理器的特殊方法。 `__enter__`方法在进入上下文管理器时被调用,它返回一个值,该值将被赋给`as`关键字后面的变量。通常,在`__enter__`方法中,我们会执行一些准备工作,例如打开文件、建立数据库连接等。 `__exit__`方法在离开上下文管理器时被调用,它接收三个参数:异常类型、异常值和追溯信息。如果在上下文中没有发生异常,那么这三个参数都为None。如果在上下文中发生了异常,那么这三个参数将包含异常的相关信息。在`__exit__`方法中,我们可以执行一些清理工作,例如关闭文件、断开数据库连接等。 下面是一个使用上下文管理器的示例: ```python class MyContextManager: def __enter__(self): print("Entering the context") return "Hello" def __exit__(self, exc_type, exc_value, traceback): print("Exiting the context") if exc_type is not None: print(f"Exception: {exc_type}, {exc_value}") with MyContextManager() as value: print(value) ``` 输出结果为: ``` Entering the context Hello Exiting the context ``` 在这个示例中,`MyContextManager`是一个自定义的上下文管理器类。在`__enter__`方法中,我们打印了进入上下文的消息,并返回了一个字符串"Hello"。在`__exit__`方法中,我们打印了离开上下文的消息,并检查是否有异常发生。 在`with`语句中,我们创建了一个`MyContextManager`的实例,并将其赋值给`value`变量。在进入上下文时,`__enter__`方法被调用,打印了"Entering the context",并返回了"Hello"。然后,我们打印了`value`的值,即"Hello"。最后,在离开上下文时,`__exit__`方法被调用,打印了"Exiting the context"。 通过使用上下文管理器,我们可以确保在进入和离开上下文时执行必要的操作,并且可以处理可能发生的异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值