Python3-22456- 013Python with关键字

Python3-22456- 013Python with关键字,第1张

        对于系统资源,如打开文件,数据库连接,socket等而言,应用程序打开这些资源并执行完业务逻辑之后,必须做的一件事就是要关闭(断开)该资源。

        使用with关键字的方法更为简洁,它的实现原理是什么?这就涉及到上下文管理器,在任何实现了__enter__() 和__exit__()方法的对象都可称之为上下文管理器

1. 以下实例代码,在Python中如何正确关闭一个文件为例使用with关键字

#Python中如何正确关闭一个文件
#普通版本
def test01():
    f = open('3.txt','w')
    f.write("0000")
    f.close()
    print("写入成功,3.txt")
    print(f.closed)
test01()

#进阶版本
def test02():
    f = open("2.txt", "w")
    try:
        f.write("1111")
        print("写入成功,2.txt")
    except Exception:
        print("ERROR")
    finally:
        f.close()
        print(f.closed)

test02()

#高级版本
def testwith():
    with open("1.txt", 'w') as f:
        f.write('2222')
        print("写入成功,1.txt")
  
testwith()

2. 用类还原with的实现原理,即__enter__()和__exit__()方法实现

class Testwith(object):
    def __init__(self,file_name,mode):
        self.file_name = file_name
        self.mode = mode

    def __enter__(self):
        self.f = open(self.file_name, self.mode)
        return self.f

    def __exit__(self, *args):
        self.f.close()

with Testwith('4.txt', 'w') as f:
    f.write('4444')
    print("4.txt写入成功,4444")
    
'''
1、首先Testwith('4.txt','w')初始化实例对象
2、with会寻找类中是否有__enter__和__exit__,如有则调用__enter__函数
3、最后__enter__()方法返回资源对象,这里就是你将要打开的那个文件对象4.txt
4、__exit__()函数方法则处理一些清理工作
'''

3. 再看一个示例代码,通过with打开,观察执行结果的输入顺序,当我们with Foo()  as foo时,此时会执行__enter__方法,即enter called,但在a = 1/0出现异常,with将会终止,此时就执行__exit__方法,就算无异常,当执行体被执行完成后,__exit__方法仍然执行一次。所以说with open('filename') as f:不用关闭文件的原因就是在__exit__方法中,存在关闭文件的 *** 作,with已经帮我们完成了这个 *** 作。

class Foo():
    def __enter__(self):
        print("enter called")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit called")
        print("exc_type:%s" % exc_type)
        print("exc_val:%s" % exc_val)
        print("exc_tb:%s" % exc_tb)

with Foo() as foo:
    print("hello world!")
    a = 1/0
    print("hello end")
        

#终端输出结果如下      
Traceback (most recent call last):
  File "C:/Users/coral/PycharmProjects/pythonProject/python with关键字04.py", line 13, in 
    a = 1/0
ZeroDivisionError: division by zero
enter called
hello world!
exit called
exc_type:
exc_val:division by zero
exc_tb:

4. 使用contextmanager装饰器,实现with功能

from contextlib import contextmanager
'''
1、Python中提供了一个contextmanager的装饰器,更进一步简化了上下文管理器的实现方式
2、通过yield将函数分割为两部分,yield之前的语句在__enter__方法中执行,yield之后的语句在__exit__方法中执行
3、紧跟在yield后面的值是函数的返回值!
'''
@contextmanager
def testwith(path, mode):
    f = open(path, mode)
    yield f
    f.close()

with testwith('5.txt', 'w') as f:
    f.write('55555')
    print("5.txt写入成功,55555")

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/868794.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存