上下文管理器和 else 块

上下文管理器

最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要。

在各种语言中 with 语句的作用不同,而且做的都是简单的事,虽然可以避免不
断使用点号查找属性,但是不会做事前准备和事后清理。

if语句之外的else块

else太个性了, 其他语言不同用 不用这个

两个风格

EAFP 这种就得看好哪个else语句了

  取得原谅比获得许可容易(easier to ask for forgiveness than permission)。这是一
种常见的 Python 编程风格,先假定存在有效的键或属性,如果假定不成立,那么捕
获异常。这种风格简单明快,特点是代码中有很多 try 和 except 语句。与其他很多
语言一样(如 C 语言),这种风格的对立面是 LBYL 风格。
接下来,词汇表定义了 LBYL。

LBYL 先用这个吧

  三思而后行(look before you leap)。这种编程风格在调用函数或查找属性或键
之前显式测试前提条件。与 EAFP 风格相反,这种风格的特点是代码中有很多 if 语
句。在多线程环境中,LBYL 风格可能会在“检查”和“行事”的空当引入条件竞争。例
如,对 if key in mapping: return mapping[key] 这段代码来说,如果在测试
之后,但在查找之前,另一个线程从映射中删除了那个键,那么这段代码就会失败。
这个问题可以使用锁或者 EAFP 风格解决。

上下文管理器和with块

上下文管理器协议包含 enterexit 两个方法。with 语句开始运行时,会在上下文管理器对象上调用 enter 方法。

with 语句运行结束后,会在上下文管理器对象上调用 exit 方法,以此扮演 finally 子句的角色。

class LookingGlass:
    def __enter__(self):
        import sys
        self.original_write = sys.stdout.write
        sys.stdout.write = self.reverse_write
        return 'JABBERWOCKY'

    def reverse_write(self, text):
        self.original_write(text[::-1])

    def __exit__(self, exc_type, exc_value, traceback):
        import sys
        sys.stdout.write = self.original_write
        if exc_type is ZeroDivisionError:
            print('Please DO NOT divide by zero!')
        return True

❻ 如果一切正常,Python 调用 exit 方法时传入的参数是 None, None, None;如
果抛出了异常,这三个参数是异常数据,如下所述。

解释器调用 enter 方法时,除了隐式的 self 之外,不会传入任何参数。传给
exit 方法的三个参数列举如下。

exc_type
异常类(例如 ZeroDivisionError)。

exc_value
  异常实例。有时会有参数传给异常构造方法,例如错误消息,这些参数可以使用exc_value.args 获取。

traceback
  traceback 对象。

@contextmanager 装饰器 哥还是写全的吧

能减少创建上下文管理器的样板代码量,因为不用编写一个完整的类,定义 enterexit 方法,

而只需实现有一个 yield 语句的生成器,生成想让 enter 方法返回的值。

总结

else 不要用python哪个没朋友的 神奇else (不过要看懂)
上下文 with

def __enter__(self): 一般返回 self自己

def __exit__(self, exc_type, exc_value, traceback):

exc_type

异常类(例如 ZeroDivisionError)。

exc_value
  异常实例。有时会有参数传给异常构造方法,例如错误消息,这些参数可以使用exc_value.args 获取。

traceback
  traceback 对象。

    原文作者:小小梁
    原文地址: https://segmentfault.com/a/1190000015758196
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞