今天在网上看到一段代码,其中使用了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. 批处理遍历文件夹执行git pull

    echo off & color 0A for /d %%f in (D:\www\*) do ( D: cd %%f chdir git pull ) pause 遍历D:\www\这个文件 ...

  2. 2018-8-10-dotnet-core-编程规范

    title author date CreateTime categories dotnet core 编程规范 lindexi 2018-08-10 19:16:52 +0800 2018-05-0 ...

  3. Thinkphp5 手册

    thinkphp5 手册 https://www.kancloud.cn/manual/thinkphp5/118003

  4. Linux 下安装中文字体

    本文以安装黑体为例,简单演示如何在Linux下安装中文字体. 环境信息介绍 [root@thatsit ~]# cat /etc/redhat-release CentOS Linux release ...

  5. Codeforces 912 质因数折半 方格数学期望

    A B #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #d ...

  6. JS比较两个时间的时间差

    /** * 比较两个时间的时间差 * @param startTime 开始时间 * @param endTime 结束时间 * @demo compareTime(new Date('2019-12 ...

  7. 1134. Vertex Cover (25)

    A vertex cover of a graph is a set of vertices such that each edge of the graph is incident to at le ...

  8. C++中vecotr表示二维数组并自己实现一个Grid类

    1 C++中使用vector来表示二维数组 声明一个二维数组: vector<vector<int>> dp(row, vector<int>(col)); 将变量 ...

  9. PHP简单的爬虫–原型

    1.PHP简单的爬虫–原型 爬虫的原理: 给定原始的url: 分析链接,根据设置的正则表达式获取链接中的内容: 有的会更新原始的url再进行分析链接,获取特定内容,周而复始. 将获取的内容保存在数据库 ...

  10. BZOJ1896 Equations 线性规划+半平面交+三分

    题意简述 给你\(3\)个数组\(a_i\),\(b_i\)和\(c_i\),让你维护一个数组\(x_i\),共\(m\)组询问,每次给定两个数\(s\),\(t\),使得 \[ \sum_i a_i ...