python3 with.py

"""
模块:python3 with.py
参考:
    https://docs.python.org/zh-cn/3/reference/compound_stmts.html#with
    https://docs.python.org/zh-cn/3/reference/datamodel.html#context-managers
    https://blog.csdn.net/lxy210781/article/details/81176687
知识点:
0.with 语句用于包装带有使用上下文管理器 (参见 with 语句上下文管理器 一节) 定义的方法的代码块的执行。
    with_stmt ::=  "with" with_item ("," with_item)* ":" suite
    with_item ::=  expression ["as" target]
    带有一个“项目”的 with 语句的执行过程如下:
        1.对上下文表达式 (在 with_item 中给出的表达式) 求值以获得一个上下文管理器。
        2.载入上下文管理器的 __enter__() 以便后续使用。
        3.载入上下文管理器的 __exit__() 以便后续使用。
        4.发起调用上下文管理器的 __enter__() 方法。
        5.如果 with 语句中包含一个目标,来自 __enter__() 的返回值将被赋值给它。
            注解: with 语句会保证如果 __enter__() 方法返回时未发生错误,则 __exit__() 将总是被调用。
                因此,如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。
                参见下面的第 6 步。
        6.执行语句体。
        7.发起调用上下文管理器的 __exit__() 方法。
            如果语句体的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给 __exit__()。
            否则的话,将提供三个 None 参数。

            如果语句体的退出是由异常导致的,并且来自 __exit__() 方法的返回值为假,则该异常会被重新引发。
            如果返回值为真,则该异常会被抑制,并会继续执行 with 语句之后的语句。

            如果语句体由于异常以外的任何原因退出,则来自 __exit__() 的返回值会被忽略,
            并会在该类退出正常的发生位置继续执行。

    实例:
        1.with EXPRESSION as TARGET:
            SUITE
        2.如果有多个项目,则会视作存在多个 with 语句嵌套来处理多个上下文管理器:
            with A() as a, B() as b:
                SUITE
            在语义上等价于:
                with A() as a:
                    with B() as b:
                        SUITE

1.with 语句上下文管理器
    上下文管理器 是一个对象,它定义了在执行 with 语句时要建立的运行时上下文。
    上下文管理器处理进入和退出所需运行时上下文以执行代码块。
    通常使用 with 语句(在 with 语句 中描述),但是也可以通过直接调用它们的方法来使用。

    上下文管理器的典型用法包括保存和恢复各种全局状态,锁定和解锁资源,关闭打开的文件等等。
    object.__enter__(self)
        进入与此对象相关的运行时上下文。
        with 语句将会绑定这个方法的返回值到 as 子句中指定的目标,如果有的话。

    object.__exit__(self, exc_type, exc_value, traceback)
        退出关联到此对象的运行时上下文。
        各个参数描述了导致上下文退出的异常。
        如果上下文是无异常地退出的,三个参数都将为 None。

        如果提供了异常,并且希望方法屏蔽此异常(即避免其被传播),则应当返回真值。
        否则的话,异常将在退出此方法时按正常流程处理。

        请注意 __exit__() 方法不应该重新引发被传入的异常,这是调用者的责任。
"""
# 1.f 绑定了一个上下文管理器。
#   此处会自动调用文件的 close()。
with open(r'./明白牌.txt', 'r', encoding="utf-8") as f:
    data = f.read()
# print("data:", data)
print(f.closed)
f = open("cs.txt")
print(f.closed)
# True
# False
#
# Process finished with exit code 0

# 2.无异常发生
class Test:
    def __enter__(self):
        print('__enter__() is called!')
        return self

    def dosomething(self):
        print('do some thing!')

    def __exit__(self, exc_type, exc_value, traceback):
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is called!')


print("\n2.")
with Test() as sample:
    sample.dosomething()


# __enter__() is called!
# do some thing!
# type:None
# value:None
# trace:None
# __exit()__ is called!

# 3.有异常发生时,会抛出异常的例子。
class Test:
    def __enter__(self):
        print('__enter__() is called!')
        return self

    def dosomething(self):
        # x = 1 / 0
        print('do some thing!')

    def __exit__(self, exc_type, exc_value, traceback):
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is called!')


print("\n3.")
with Test() as sample:
    sample.dosomething()


# __enter__() is called!
# type:<class 'ZeroDivisionError'>
# value:division by zero
# trace:<traceback object at 0x000001B2B622AA80>
# __exit()__ is called!
# Process finished with exit code 1

# 4.有异常发生时,不抛出异常的例子:
class Test:
    def __enter__(self):
        print('__enter__() is called!')
        return self

    def dosomething(self):
        x = 1 / 0
        print('do some thing!')

    def __exit__(self, exc_type, exc_value, traceback):
        print(f'type:{exc_type}')
        print(f'value:{exc_value}')
        print(f'trace:{traceback}')
        print('__exit()__ is called!')
        return True


print("\n4.")
with Test() as sample:
    sample.dosomething()
# __enter__() is called!
# type:<class 'ZeroDivisionError'>
# value:division by zero
# trace:<traceback object at 0x0000013DCDE4C040>
# __exit()__ is called!
# Process finished with exit code 0




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值