今天在网上看到一段代码,其中使用了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. 剑指offer-从尾到头打印链表-链表-python

    题目描述 输入一个链表,按链表从尾到头的顺序返回一个ArrayList. 把链表依次放入list里面,反向打印 # -*- coding:utf-8 -*- # class ListNode: # d ...

  2. 修改admin中App的名称与表的名称

    修改APP的名称: # coding:utf-8 from django.apps import AppConfig import os default_app_config = 'repositor ...

  3. ETL工具Kettle使用以及与Java整合实现数据清洗

    本文主要讲述kettle的使用和与Java整合,具体下载与安装请自行百度! kettle有两种脚本方式:转换和工作,工作中可以添加转换.以下以转换为例. 1.新建一个转换, 2.在工作中经常用到的是表 ...

  4. react 从商品详情页返回到商品列表页,列表自动滚动上次浏览的位置

    现状:目前从商品详情页返回到商品列表页,还需要再去请求服务数据,还需要用户再去等待获取数据的过程,这样用户体验非常不好, 遇到的问题: 1:如何将数据缓存, 2:如何获取和保存列表滑动的高度, 3:判 ...

  5. SPSS25 下载安装和激活

    目录 1. 其他版本 2. 安装步骤 3. 下载地址 1. 其他版本 参考:https://www.cnblogs.com/coco56/p/11648399.html 2. 安装步骤 打开安装包 下 ...

  6. npm 在安装的时候提示 没有权限操作的解决办法 Error: EACCES: permission denied

    十分感谢https://blog.csdn.net/ldqsxsl/article/details/75059607的帮助! 错误原因:权限错误,需要root用户. 解决办法:就是把用户目录下的 .n ...

  7. .net core Consul

    创建API项目修改Program public class Program { public static void Main(string[] args) { CreateWebHostBuilde ...

  8. 043:Django使用原生SQL语句操作数据库

    Django使用原生SQL语句操作数据库 Django配置连接数据库: 在操作数据库之前,首先先要连接数据库.这里我们以配置 MySQL 为例来讲解. Django 连接数据库,不需要单独的创建一个连 ...

  9. 开始玩矩阵了!先来一道入门题![SDOI2008]递归数列

    [SDOI2008]递归数列 题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + c ...

  10. 【bzoj3262】陌上花开

    题目描述: 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa& ...