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)
python中关于with以及contextlib的使用的更多相关文章
- Python 上下文管理器模块--contextlib
在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...
- Python中操作mysql的pymysql模块详解
Python中操作mysql的pymysql模块详解 前言 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同.但目前pymysql支持python3.x而后者不支持 ...
- Python中With的用法
在看Dive Into Python中有关描述文件读写那章节的时候,看到了有关with的用法,查阅下相关资料,记录下来,以备后用. 官方的reference上有关with statement是这样说的 ...
- Python中的上下文管理器和with语句
Python2.5之后引入了上下文管理器(context manager),算是Python的黑魔法之一,它用于规定某个对象的使用范围.本文是针对于该功能的思考总结. 为什么需要上下文管理器? 首先, ...
- (转)Python中操作mysql的pymysql模块详解
原文:https://www.cnblogs.com/wt11/p/6141225.html https://shockerli.net/post/python3-pymysql/----Python ...
- (转)Python中的上下文管理器和Tornado对其的巧妙应用
原文:https://www.binss.me/blog/the-context-manager-of-python-and-the-applications-in-tornado/ 上下文是什么? ...
- python中实现上下文管理器的两种方法
上下文管理器: python中实现了__enter__和__exit__方法的对象就可以称之为上下文管理器 实现方法一举例: def File(object): def __init__(self, ...
- Python中的多线程编程,线程安全与锁(一)
1. 多线程编程与线程安全相关重要概念 在我的上篇博文 聊聊Python中的GIL 中,我们熟悉了几个特别重要的概念:GIL,线程,进程, 线程安全,原子操作. 以下是简单回顾,详细介绍请直接看聊聊P ...
- 深入浅析python中的多进程、多线程、协程
深入浅析python中的多进程.多线程.协程 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源 ...
随机推荐
- 线程的 run()和 start()有什么区别?(未完成)
线程的 run()和 start()有什么区别?(未完成)
- 作业十一——LL(1)文法的判断
1. 文法 G(S): (1)S -> AB (2)A ->Da|ε (3)B -> cC (4)C -> aADC |ε (5)D -> b|ε 验证文法 G(S)是不 ...
- SQL JOB实现数据库同步
数据库同步是一种比较常用的功能.以下结合我自己的体会整理的,如果有理解不完全或者有误的地方望大牛不理赐教.下面介绍的就是数据库同步的两种方式: 1.SQL JOB的方式 sql Job的方式同步数据 ...
- 从c到c++<四>
总结一下:内联函数实际上就是用inline修饰的函数,这些函数会在编译时由编译器来将代码展开,而不用像上面第二点提到的人工展开,它的使用场景:代码很短.使用频率高. 具体代码如下: 对于这两者实际上还 ...
- 2018 CERC 混合博弈
N堆石子 先手最多拿A个 后手最多拿B个 每次都至少要拿一个 谁先取完谁赢 如果A和B相等直接就是一个bash博弈 如果一个石堆的石子数少于min(A,B) 则是个nim游戏 我们先讨论只有N=1且A ...
- 大数据之路week04--day05(java 正则表达式)
1.1 正则表达式 1.2 简介 Regular Expression 正则表达式 常简称为: regex.正则 正则表达式是一整套约束字符串的语法规则,独立于任何编程语言 正则表达式 方便.灵 ...
- idea 查看类继承关系的快捷键
类似eclipse ctrl+t的快捷键,idea中是ctrl+H
- hibernate配置和映射文件
映射文件 <?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping ...
- 2018HDU多校联赛第六场 6373 Pinball——水题&&物理题
题意 给定一个斜面,从某处让一个小球作自由落体运动,求小球与斜面的碰撞次数(假设都为弹性碰撞). 分析 题图如下,x轴.y轴是虚拟的. 根据高中物理的套路,沿斜面方向分解重力加速度即可. #inclu ...
- RedisTemplate 中 opsForHash()使用 (没有测试过,copy的)
1.put(H key, HK hashKey, HV value) //新增hashMap值 redisTemplate.opsForHash().put("hashValue" ...