- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python中的with语句与上下文管理器学习总结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
0、关于上下文管理器 上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象.
1
2
|
with manager as var:
do_something(var)
|
相当于以下情况的简化:
1
2
3
4
5
|
var
=
manager.__enter__()
try
:
do_something(var)
finally
:
manager.__exit__()
|
换言之,PEP 343中定义的上下文管理器协议允许将无聊的try...except...finally结构抽象到一个单独的类中,仅仅留下关注的do_something部分.
__enter__方法首先被调用。它可以返回赋给var的值。as部分是可选的:如果它不出现,enter的返回值简单地被忽略。 with语句下的代码被执行。就像try子句,它们或者成功执行到底,或者break,continue或return,或者可以抛出异常。无论哪种情况,该块结束后,__exit__方法被调用。如果抛出异常,异常信息被传递给__exit__,这将在下一章节讨论。通常情况下,异常可被忽略,就像在finally子句中一样,并且将在__exit__结束后重新抛出。 比如说我们想确认一个文件在完成写操作之后被立即关闭:
1
2
3
4
5
6
7
8
9
|
>>>
class
closing(
object
):
...
def
__init__(
self
, obj):
...
self
.obj
=
obj
...
def
__enter__(
self
):
...
return
self
.obj
...
def
__exit__(
self
,
*
args):
...
self
.obj.close()
>>> with closing(
open
(
'/tmp/file'
,
'w'
)) as f:
... f.write(
'the contents\n'
)
|
这里我们确保了当with块退出时调用了f.close()。因为关闭文件是非常常见的操作,该支持已经出现在file类之中。它有一个__exit__方法调用close,并且本身可作为上下文管理器.
1
2
|
>>> with
open
(
'/tmp/file'
,
'a'
) as f:
... f.write(
'more contents\n'
)
|
try...finally常见的用法是释放资源。各种不同的情况实现相似:在__enter__阶段资源被获得,在__exit__阶段释放,如果抛出异常也被传递。正如文件操作,往往这是对象使用后的自然操作,内置支持使之很方便。每一个版本,Python都在更多的地方提供支持.
1、如何使用上下文管理器:
如何打开一个文件,并写入"hello world" 。
1
2
3
4
5
|
filename
=
"my.txt"
mode
=
"w"
writer
=
open
(filename,mode)
writer.write(
"hello world"
)
writer.close()
|
当发生异常时(如磁盘写满),就没有机会执行第5行。当然,我们可以采用try-finally语句块进行包装:
1
2
3
4
5
|
writer
=
open
(filename,mode)
try
:
writer.write(
"hello world"
)
finally
:
writer.close()
|
当我们进行复杂的操作时,try-finally语句就会变得丑陋,采用with语句重写:
1
2
|
with
open
(filename,mode) as writer:
writer.write(
"hello world"
)
|
as指代了从open()函数返回的内容,并把它赋给了新值。with完成了try-finally的任务.
2、自定义上下文管理器 。
with语句的作用类似于try-finally,提供一种上下文机制。要应用with语句的类,其内部必须提供两个内置函数__enter__和__exit__。前者在主体代码执行前执行,后者在主体代码执行后执行。as后面的变量,是在__enter__函数中返回的.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class
echo():
def
output(
self
):
print
"hello world"
def
__enter__(
self
):
print
"enter"
return
self
#可以返回任何希望返回的东西
def
__exit__(
self
,exception_type,value,trackback):
print
"exit"
if
exception_type
=
=
ValueError:
return
True
else
:
return
Flase
>>>with echo as e:
e.output()
|
1
2
3
|
enter
hello world
exit
|
1
|
def
__exit__(
self
,exc_type,exc_value,exc_tb)
|
其中,exc_type:异常类型;exc_value:异常值;exc_tb:异常追踪信息 。
当__exit__返回True时,异常不传播 。
3、contextlib模块 。
contextlib模块的作用是提供更易用的上下文管理器,它是通过Generator实现的。contextlib中的contextmanager作为装饰器来提供一种针对函数级别的上下文管理机制,常用框架如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from
contextlib
import
contextmanager
@contextmanager
def
make_context():
print
'enter'
try
:
yield
"ok"
except
RuntimeError,err:
print
'error'
,err
finally
:
print
'exit'
>>>with make_context() as value:
print
value
|
输出为:
1
2
3
|
enter
ok
exit
|
其中,yield写入try-finally中是为了保证异常安全(能处理异常)as后的变量的值是由yield返回。yield前面的语句可看作代码块执行前操作,yield之后的操作可以看作在__exit__函数中的操作.
以线程锁为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@contextlib
.contextmanager
def
loudLock():
print
'Locking'
lock.acquire()
yield
print
'Releasing'
lock.release()
with loudLock():
print
'Lock is locked: %s'
%
lock.locked()
print
'Doing something that needs locking'
#Output:
#Locking
#Lock is locked: True
#Doing something that needs locking
#Releasing
|
4、contextlib.nested:减少嵌套 。
对于:
1
2
3
|
with
open
(filename,mode) as reader:
with
open
(filename1,mode1) as writer:
writer.write(reader.read())
|
可以通过contextlib.nested进行简化:
1
2
|
with contextlib.nested(
open
(filename,mode),
open
(filename1,mode1)) as (reader,writer):
writer.write(reader.read())
|
在python 2.7及以后,被一种新的语法取代:
1
2
|
with
open
(filename,mode) as reader,
open
(filename1,mode1) as writer:
writer.write(reader.read())
|
5、contextlib.closing() 。
file类直接支持上下文管理器API,但有些表示打开句柄的对象并不支持,如urllib.urlopen()返回的对象。还有些遗留类,使用close()方法而不支持上下文管理器API。为了确保关闭句柄,需要使用closing()为它创建一个上下文管理器(调用类的close方法).
1
2
3
4
5
6
7
8
9
|
import
contextlib
class
myclass():
def
__init__(
self
):
print
'__init__'
def
close(
self
):
print
'close()'
with contextlib.closing(myclass()):
print
'ok'
|
输出:
1
2
3
|
__init__
ok
close()
|
最后此篇关于Python中的with语句与上下文管理器学习总结的文章就讲到这里了,如果你想了解更多关于Python中的with语句与上下文管理器学习总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我之前让 dll 注入(inject)器变得简单,但我有 Windows 7,我用 C# 和 C++ 做了它,它工作得很好!但是现在当我在 Windows 8 中尝试相同的代码时,它似乎没有以正确的方
我正在尝试制作一个名为 core-splitter 的元素,该元素在 1.0 中已弃用,因为它在我们的项目中起着关键作用。 如果您不知道 core-splitter 的作用,我可以提供一个简短的描述。
我有几个不同的蜘蛛,想一次运行所有它们。基于 this和 this ,我可以在同一个进程中运行多个蜘蛛。但是,我不知道如何设计一个信号系统来在所有蜘蛛都完成后停止 react 器。 我试过了: cra
有没有办法在达到特定条件时停止扭曲 react 器。例如,如果一个变量被设置为某个值,那么 react 器应该停止吗? 最佳答案 理想情况下,您不会将变量设置为一个值并停止 react 器,而是调用
https://code.angularjs.org/1.0.0rc9/angular-1.0.0rc9.js 上面的链接定义了外部js文件,我不知道Angular-1.0.0rc9.js的注入(in
我正在尝试运行一个函数并将服务注入(inject)其中。我认为这可以使用 $injector 轻松完成.所以我尝试了以下(简化示例): angular.injector().invoke( [ "$q
在 google Guice 中,我可以使用函数 createInjector 创建基于多个模块的注入(inject)器。 因为我使用 GWT.create 在 GoogleGin 中实例化注入(in
我在 ASP.NET Core 1.1 解决方案中使用配置绑定(bind)。基本上,我在“ConfigureServices Startup”部分中有一些用于绑定(bind)的简单代码,如下所示: s
我在 Spring MVC 中设置 initBinder 时遇到一些问题。我有一个 ModelAttribute,它有一个有时会显示的字段。 public class Model { privat
我正在尝试通过jquery post发布knockoutjs View 模型 var $form = $('#barcodeTemplate form'); var data = ko.toJS(vm
如何为包含多态对象集合的复杂模型编写自定义模型绑定(bind)程序? 我有下一个模型结构: public class CustomAttributeValueViewModel { publi
您好,我正在尝试实现我在 this article 中找到的扩展方法对于简单的注入(inject)器,因为它不支持开箱即用的特定构造函数的注册。 根据这篇文章,我需要用一个假的委托(delegate)
你好,我想自动注册我的依赖项。 我现在拥有的是: public interface IRepository where T : class public interface IFolderReposi
我正在使用 Jasmine 测试一些 Angular.js 代码。为此,我需要一个 Angular 注入(inject)器: var injector = angular.injector(['ng'
我正在使用 Matlab 代码生成器。不可能包含代码风格指南。这就是为什么我正在寻找一个工具来“ reshape ”、重命名和重新格式化生成的代码,根据我的: 功能横幅约定 文件横幅约定 命名约定 等
这个问题在这里已经有了答案: Where and why do I have to put the "template" and "typename" keywords? (8 个答案) 关闭 8
我开发了一种工具,可以更改某些程序的外观。为此,我需要在某些进程中注入(inject)一个 dll。 现在我基本上使用这个 approach .问题通常是人们无法注入(inject) dll,因为他们
我想使用 swing、spring 和 hibernate 编写一个 java 应用程序。 我想使用数据绑定(bind)器用 bean 的值填充 gui,并且我还希望它反射(reflect) gui
我有这段代码,当两个蜘蛛完成后,程序仍在运行。 #!C:\Python27\python.exe from twisted.internet import reactor from scrapy.cr
要点是 Spring Batch (v2) 测试框架具有带有 @Autowired 注释的 JobLauncherTestUtils.setJob。我们的测试套件有多个 Job 类提供者。因为这个类不
我是一名优秀的程序员,十分优秀!