上下文管理器和 else 块

上下文管理器

最终,上下文管理器可能几乎与子程序(subroutine)自己同样重要。python

在各类语言中 with 语句的做用不一样,并且作的都是简单的事,虽然能够避免不
断使用点号查找属性,可是不会作事前准备和过后清理。编程

if语句以外的else块

else太个性了, 其余语言不一样用 不用这个多线程

两个风格

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

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

LBYL 先用这个吧

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

上下文管理器和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 方法的三个参数列举以下。code

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 对象。

相关文章
相关标签/搜索