如何在“with”块中实例化对象?

时间:2016-12-21 08:45:02

标签: python

我在python解释器(2.7.13)中完成了以下操作:

>>> class test:
...     def __init__(self):
...             print "Object has been constructed!"
...     def __enter__(self):
...             print "Entering with"
...     def __exit__(self, type, value, traceback):
...             print "Exiting with"
... 
>>> 
>>> t1 = test()
Object has been constructed!
>>> print t1
<__main__.test instance at 0x7fed5383e3b0>
>>> 
>>> with test() as t1:
...     print "Inside 'with' block"
...     print t1
... 
Object has been constructed!
Entering with
Inside 'with' block
None
Exiting with

我的问题是:为什么print会在none块中输出with?对象似乎由with实例化(至少,我们可以看到对构造函数的调用),但是命名空间中似乎不存在t1。这是正常的吗?

2 个答案:

答案 0 :(得分:4)

打印None,因为__enter__返回None(隐式)。

考虑以下示例:

class test:
    def __init__(self):
        print "Object has been constructed!"
    def __enter__(self):
        print "Entering with"
        return 5
    def __exit__(self, type, value, traceback):
        print "Exiting with"

with test() as t1:
    assert t1 == 5

AssertionError未被提升,因此我们知道t1等于5。

通常,something中分配给with ctx_mgr as something:的值可以是任何内容,而不是严格ctx_mgr。如果必须是ctx_mgr,则with ... as ...构造将是多余的。

答案 1 :(得分:3)

您需要在上下文管理器方法self中返回__enter__(或根据您的需要使用任何其他对象);此函数的结果已分配给as

class test:
    ...
    def __enter__(self):
            print( "Entering with")
            return self
    ...

如何在python context manager types中描述它。