<!-- TOC -->python
<!-- /TOC -->code
看一个例子:对象
def get_result(): a = 3 b = 0 try: b = 3 / 0 except Exception as e: print("ERROR=", e) finally: print("a=", a) if __name__ == "__main__": get_result()
返回结果是:字符串
ERROR= division by zero a= 3
总结:get
try..except..else没有捕获到异常,执行else语句
try..except..finally无论是否捕获到异常,都执行finally语句
python文本文件读写的3种方法it
# 第一种方法: file1 = open("test.txt") file2 = open("output.txt", "w") while True: line = file1.readline() # 这里能够进行逻辑处理 file2.write(line) if not line: break # 记住文件处理完,关闭是个好习惯 file1.close() file2.close() # 读文件有3种方法: # - read()将文本文件全部行读到一个字符串中。 # - readline()是一行一行的读 # - readlines()是将文本文件中全部行读到一个list中,文本文件每一行是list的一个元素。 # 优势:readline()能够在读行过程当中跳过特定行。 # 第二种方法:文件迭代器,用for循环的方法 file2 = open("output.txt", "w") for line in open("test.txt"): # 这里能够进行逻辑处理 file2.write(line) # 第三种方法: 推荐使用这个方法文件上下文管理器 with open('somefile.txt', 'r') as f: data = f.read() with open('somefile.txt', 'r') as f: for line in f: print(line) with open('somefile.txt', 'w') as f: f.write("hello")
这里重点说说第三种方法io
打开文件在进行读写的时候可能会出现一些异常情况,若是按照常规的f.open
写法,咱们须要try,except,finally,作异常判断,而且文件最终无论遇到什么状况,都要执行finally f.close()关闭文件,with方法帮咱们实现了finally中f.closefor循环
上下文管理器协议包含__enter__ 和 __exit__
两个方法。class
with 语句开始运行时,会在上下文管理器对象上调用 __enter__
方法。
with 语句运行结束后,会在上下文管理器对象上调用 __exit__
方法,以此扮演 finally 子句的角色。
最多见的例子是确保关闭文件对象
class T(object): def __enter__(self): print('T.__enter__') return '我是__enter__的返回值' def __exit__(self, exc_type, exc_val, exc_tb): print('T.__exit__') with T() as t: print(t)
返回结果:
T.__enter__ 我是__enter__的返回值 T.__exit__
with之于上下文管理器,就像for之于迭代器同样。with就是为了方便上下文管理器的使用。
下文管理器就不得不提一下@contextmanager 装饰器,它能减小建立上下文管理器的样板代码量,
由于不用编写一个完整的类,定义 __enter__和 __exit__
方法,而只需实现有一个 yield 语句的生成器,生成想让 __enter__
方法返回的值。
@contextmanager 装饰器优雅且实用,把三个不一样的 Python 特性结合到了一块儿:函数装饰器、生成器和 with 语句。
在使用 @contextmanager 装饰的生成器中,yield 语句的做用是把函数的定义体分红两部分:
1. yield 语句前面的全部代码在 with 块开始时(即解释器调用` __enter__` 方法时)执行 2. yield 语句后面的代码在with 块结束时(即调用 `__exit__` 方法时)执行。
例子:
import sys import contextlib @contextlib.contextmanager def WoHa(n): original_write = sys.stdout.write def reverse_write(text): original_write(text[::-1]) sys.stdout.write = reverse_write yield n sys.stdout.write = original_write return True obj1 = WoHa('你手机拿反了') with obj1 as content: print('哈哈镜花缘') print(content) print('#### with 执行完毕后,在输出content: ####') print(content)
返回结果:
缘花镜哈哈 了反拿机手你 #### with 执行完毕后,在输出content: #### 你手机拿反了
这里咱们须要注意的是:
代码执行到yield时,会产出一个值,这个值会绑定到 with 语句中 as 子句的变量上。执行 with 块中的代码时,这个函数会在yield这里暂停。