今天在网上看到一段代码,其中使用了with seam:初见不解其意,遂查询资料.

代码:

 #! /usr/bin/env python
# -*- coding:utf-8 -*-
import time
from random import random
from threading import Thread,Semaphore sema = Semaphore(3) def foo(tid):
with sema:
print("{} acquire sema".format(tid))
wt = random() * 2
time.sleep(wt)
print("{} release sema".format(tid)) threads = [] for i in range(5):
t = Thread(target=foo,args=(i,))
threads.append(t)
t.start() for t in threads:
t.join()

查询 python核心编程第二版,其中有个章节,专门介绍了with语句和上下文管理.

with语句,在Python2.6正式启用,和try-except-finally 类似,with语句也是用来简化代码的.Python中,并非任意符号都可以使用with语句,with语句仅仅工作于支持上下文管理协议的对象.

with应用场景:打开文件,日志,数据库,线程资源,简单同步,数据库连接等等.

 with context_expr [as var]:   ##context_expr:上下文表达式,[]可选
with_suite

能和with一起使用的成员列表:

 file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore

最最常见的with用法:

 with open("file","r") as f:
for line in f:
pass

上面的代码都做了什么操作?

程序试图打开一个文本,如果一切正常,把文本对象赋值给f,然后用迭代器遍历文本中的每一行.当完成时,关闭文本.

无论在这段代码的开始,中间,还是结束时发生了异常,都会执行清理的代码,此外文件仍然被会自动的关闭.

先上一个最简单的代码:

 class Context:
def __init__(self,name):
self.name = name
def __enter__(self):
print("Begin.__enter__")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("End.__exit__")
def context(self):
print("This is context ...{}".format(self.name)) with Context("xurui") as context: ##如果带上 as 变量,那么__enter__()方法必须得返回一个东西,要不然会报错..
context.context()
with Context("xurui"):
Context("xurui").context()

演示代码:

class Sample:
"""
##执行__enter__方法,它将完成with语句块执行前的所有准备工作,如果with xx 后面带上参数,as val,那么__enter__返回值将赋值给
val,否则,丢弃返回值"""
def __enter__(self):
print("In __enter__()")
return "Foo" ##返回"Foo"给as Sample中的Sample
def __exit__(self, exc_type, exc_val, exc_tb):
print("In __exit__()") def get_sample():
print(type(Sample()))
return Sample() with get_sample() as Sample:
print("sample:{}".format(Sample)) 结果:
In __enter__()
sample:Foo
In __exit__()

但这都不是with的牛逼功能,with最强的地方,还是用来处理异常...

__exit__(),有三个参数,类型(异常类),值(异常实例),和回溯(回溯对象).

演示代码:

class Sample:
"""
##执行__enter__方法,它将完成with语句块执行前的所有准备工作,如果with xx 后面带上参数,as val,那么__enter__返回值将赋值给
val,否则,丢弃返回值"""
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("type:{},\nvalue:{},\ntrace:{}".format(exc_type,exc_val,exc_tb)) def do_something(self):
bar = 1 / 0
return bar + 10 with Sample() as Sample:
Sample.do_something()
print("sample:{}".format(Sample)) 结果:
type:<class 'ZeroDivisionError'>,
value:division by zero,
trace:<traceback object at 0x0000000001074CC8>
Traceback (most recent call last):
File "C:/Users/xurui/PycharmProjects/q1/2017-03-01/error.py", line 55, in <module>
Sample.do_something()
File "C:/Users/xurui/PycharmProjects/q1/2017-03-01/error.py", line 51, in do_something
bar = 1 / 0
ZeroDivisionError: division by zero
 import queue
import contextlib @contextlib.contextmanager
def worker_state(xxx, val):
xxx.append(val)
# print(xxx)
try:
yield
finally:
xxx.remove(val)
# print(xxx) q = queue.Queue()
li = []
q.put("xurui")
with worker_state(li, 1):
print("before", li)
q.get()
print("after", li)

自定义一个open文件

 import contextlib

 @contextlib.contextmanager
def MyOpen(filename, mode):
try:
f = open(filename, mode, encoding='utf')
except Exception as e:
pass
else:
yield f ##f return 给 as f的f
finally:
f.close() with MyOpen("1.py", 'r') as f:
ret = f.readlines()
print(ret)

python上下文管理,with语句的更多相关文章

  1. python上下文管理

    一.python上下文介绍: python中的上下文,指的就是代码所执行的环境状态,或者运行的场景 python上下文管理器规定了某个对象的使用范围,当进入或者离开了使用范围,会有相应的操作,多用于资 ...

  2. python上下文管理器ContextLib及with语句

    http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...

  3. python上下文管理器及with语句

    with语句支持在一个叫上下文管理器的对象的控制下执行一系列语句,语法大概如下: with context as var: statements 其中的context必须是个上下文管理器,它实现了两个 ...

  4. python 上下文管理器

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 上下文管理器(context manager)是Python2.5开始支持的一种语 ...

  5. Python 上下文管理器和else块

    最终,上下文管理器可能几乎与子程序(subroutine)本身一样重要.目前,我们只了解了上下文管理器的皮毛--Basic 语言有with 语句,而且很多语言都有.但是,在各种语言中 with 语句的 ...

  6. Python上下文管理器

    在Python中让自己创建的函数.类.对象支持with语句,就实现了上线文管理协议.我们经常使用with open(file, "a+") as f:这样的语句,无需手动调用f.c ...

  7. Python上下文管理器 with

    对于系统资源的操作,如:文件操作.数据库操作等,我们往往打开文件.连接数据库后忘了将其close掉,这时就可能会引发异常,因此我们常用的做法是: # coding:utf-8 f = open(&qu ...

  8. Python上下文管理协议:__enter__和__exit__

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语 ...

  9. Python上下文管理器(Context managers)

    上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源. 使用上下文管理器最广泛的案例就是with语句了.想象下你有两个需要结对执行的相关操作,然后还 ...

随机推荐

  1. C++关于erase的复杂度(转载)

    被这个问题困扰了很多次,有必要整理一下. 当然最好的参考资料就是http://www.cplusplus.com/reference/set/set/erase/ 里的Complexcity部分了,但 ...

  2. mongodb启动报错,child process failed, exited with error number 1

    error: child process failed, exited with error number 1 第一次安装mongodb,随后启动一般不会出现上面的错误,出现这种错误的原因一般是mon ...

  3. Linux安装Jenkins并部署springboot项目

    安装步骤: 1.跳转连接https://pkg.jenkins.io/redhat-stable/下载安装包 2.安装命令: sudo rpm -ih jenkins-2.73.2-1.1.noarc ...

  4. node搭建个人博客promise警告解除

    警告 (node:8500) UnhandledPromiseRejectionWarning: undefined (node:8500) UnhandledPromiseRejectionWarn ...

  5. Spark Streaming整合Flume + Kafka wordCount

    flume配置文件 flume_to_kafka.conf a1.sources = r1 a1.sinks = k1 a1.channels = c1 a1.sources.r1.type = sp ...

  6. jQuery实现动态时间

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  7. 41. First Missing Positive (JAVA)

    Given an unsorted integer array, find the smallest missing positive integer. Example 1: Input: [1,2, ...

  8. 对数据集做标准化处理的几种方法——基于R语言

    数据集——iris(R语言自带鸢尾花包) 一.scale函数 scale函数默认的是对制定数据做均值为0,标准差为1的标准化.它的两个参数center和scale: 1)center和scale默认为 ...

  9. linux NFS 自动挂载

    NFS 自动挂载的两种方法 第一种: 需要注意的事项 开机挂载的命令不能写入到/etc/fstab 中,由于 NFS 依赖于网络,而/etc/fstab 的引用是在计算机 网络尚未启动的时候就开始引导 ...

  10. Cookie、Session和Django分页

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...