zoukankan      html  css  js  c++  java
  • python中关于with以及contextlib的使用

    一般在coding时,经常使用with来打开文件进行文件处理,然后无需执行close方法进行文件关闭.

    with open('test.py','r' as f:
    	print(f.readline())
    

    with的作用,类似于try...finally...,提供一种上下文机制.如果需要使用with语句的类,就必须内部提供了两个内置函数__enter__和__exit__,前者在主体代码前执行,后者在主体代码后执行.看下下面的例子吧.

    class Tt:
        def output(self):
            print('hello,world!')
    
        def __enter__(self):
            print('enter!!!')
            return self
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('exit!!!')
            if exc_type == ValueError:
                return True
            else:
                return False
    
    with Tt() as t:
        t.output()
        print('do something~~')
    print('==================')
    with Tt() as e:
        raise ValueError('value error!')
    print('==================')
    with Tt() as e:
        raise Exception('can not detect! ')
    

    out:

    enter!!!
    hello,world!
    do something~~
    exit!!!
    ==================
    enter!!!
    exit!!!
    ==================
    enter!!!
    Traceback (most recent call last):
    exit!!!
      File "/Users/shane/PycharmProjects/Py_study/Base/S12/with_test.py", line 29, in <module>
        raise Exception('can not detect! ')
    Exception: can not detect! 
    

    是不是跟装饰器有点像?再来个contextlib吧!

    contextlib是为了加强with语句,提供上下文机制的模块,它是通过Generator实现的。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制。下面看个例子吧:

    import contextlib
    free_list=[]
    work_thread='alex'
    
    @contextlib.contextmanager
    def worker_state(state_list,work_thread):
        state_list.append(work_thread)
        try:
            print('go on!!')        #step1
            yield                   #step2
        finally:
            print(state_list)       #step5
            state_list.remove(work_thread)      #step6
            print(state_list)       #step7
    
    
    with worker_state(free_list,work_thread):
        print(123)                  #step3
        print(456)                  #step4
    

    out:

    go on!!
    123
    456
    ['alex']
    []
    

    contextlib.contextmanager 是python中内置的一个装饰器:执行with后面的函数时,先进入函数中执行,遇到yield时,跳出,执行下面的,最后执行函数中的finally

    此种用法也可用来自动关闭socket

    import contextlib,socket
    
    @contextlib.contextmanager
    def context_socket(host,port):
        sk=socket.socket()
        sk.bind((host,port))
        sk.listen(5)
        try:
            yield sk		#将sk返回,赋值给sock
        finally:
            sk.close()
    
    with context_socket('127.0.0.1',8888) as sock:
        print(sock)
    
  • 相关阅读:
    转ihone程序内发邮件,发短信,打开链接等
    plist 文件的读写
    转object c语法速成
    转iphone项目之间的引用。
    object c求nsstring 长度和去掉前后空格的方法
    object c runtime中类类型和消息支持检查
    转NSDictionary类使用
    设置UITableview 浮动的 header
    NSString 类型plist转为NSDictionary
    ObjectiveC Unicode 转换成中文
  • 原文地址:https://www.cnblogs.com/ccorz/p/5702483.html
Copyright © 2011-2022 走看看