打卡8

mac2024-05-25  51

Python:with语句

参考学习链接:Python之with语句

打开文件的时候通常要考虑异常情况,比如:

try: ccfile = open('/path/data') content = ccfile.readlines() ccfile.close() except IOError: log.write('no data read\n')

↑ 如果文件操作出现异常,则写一条错误日志;

如果文件打开成功,但readlines() 调用失败,异常处理会立即跳转到except处执行,文件关闭不被执行。 解决办法:将close() 语句放到finally子句中。 (finally:不管有无异常,都会被执行)

try: try: ccfile = open('/path/data') content = ccfile.readlines() except IOError: log.write('no data read\n') finally ccfile.close()

try: try: ccfile = open('/path/data') content = ccfile.readlines() finally IOError: ccfile.close() except IOError: log.write('no data read\n')

为了方便简洁,使用with语句把try、except、 finally关键字和资源分配、释放相关代码统统去掉:

with open(’/etc/passwd’) as f: for line in f: print(line)

with语句仅仅能对支持上下文管理协议的对象使用。支持本协议的对象

filedecimal.Contextthread.LockTypethreading.Lockthreading.RLockthreading.Conditionthreading.Semaphorethreading.BoundedSemaphore

with语句执行的解析:

with context_expr() as var: doSomething()

当with语句执行时,便执行上下文表达式(context_expr)(一般为某个方法)来获得一个上下文管理器对象,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节: 一旦获得了上下文对象,就会调用它的__enter__()方法,将完成with语句块执行前的所有准备工作,如果with语句后面跟了as语句,则用__enter__()方法的返回值来赋值; 当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,exit()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。 因为上下文管理器主要作用于共享资源,enter()和__exit__()方法基本是完成的是分配和释放资源的低层次工作,比如:数据库连接、锁分配、信号量加/减、状态管理、文件打开/关闭、异常处理等。

自定义类使用with来管理

class A(object): def __enter__(self): print('__enter__() called') return self def print_hello(self): print("hello world!") def __exit__(self, e_t, e_v, t_b): print('__exit__() called') #首先会执行__enter__方法 with A() as a: # a为__enter__的返回对象 a.print_hello() print('got instance') #结束会执行__exit__方法

输出结果:

__enter__() called hello world! got instance __exit__() called

contextlib模块实现上下文自动管理

@contextmanager def context(): print('entering the zone') try: yield except Exception as e: print('with an error %s'%e) raise e else: print('with no error') with context(): print('----in context call------')

输出:

entering the zone ----in context call------ with no error
最新回复(0)