使用语句

时间:2015-05-10 06:26:37

标签: python

嘿,伙计们是python开发的新手,我试图理解使用with ..我写的代码是

  class Mgr(object):

       def __enter__(self): pass
       def __exit__(self, ext, exv, trb):
          if ext is not None: print "no not possible"
                 print "OK I caught you"
                 return True

       def honey(self):
           print 'guli'



b = Mgr()
with b.honey() as d:
        print d

当我运行代码时,它会输出guli输出以及属性错误。

我知道上下文管理器的工作,并且b.honey()是一个上下文管理器??你们可以解释一下为什么会出现这个错误..感谢帮助..

Traceback (most recent call last): File "C:/Python27/c", line 18, in <module> with b.honey() as d: AttributeError: __exit__

1 个答案:

答案 0 :(得分:2)

问题是,虽然b是上下文管理员,b.honey()不是。

b.honey()就是您从honey方法返回的内容。在这种情况下,您不会返回任何内容,因此None

如果您希望b.honey()返回b,您可以 - 只需将return self添加到方法的末尾。但这有点奇怪。您通常不希望在b.honey()语句中使用with来关闭&#34;关闭&#34; b。这就像with f.read(8192) as buf:关闭文件f。 (有些用例可能有意义,但一般情况下不一样。)

或者,没有理由bb.honey()都不能完全独立的上下文管理器。很难想象你想要这个的情况,但如果你这样做,你可以返回其他类的实例 - 或者使用contextmanager装饰器:

@contextlib.contextmanager
def honey(self):
    print 'guli'
    yield 'this is d'
    print 'ilug'

但更有可能的是,你真正想要的是这样的:

with Mgr() as d:
    d.honey()
    print d

但在这种情况下,您可能希望将__enter__方法更改为return self。无论它返回什么,最终会在d中结束。

所以,例如:

class Mgr(object):
     def __enter__(self): 
         return self
     def __exit__(self, ext, exv, trb):
         if ext is not None: print "no not possible"
         print "OK I caught you"
         return True

    def honey(self):
        print 'guli'

with Mgr() as d:
    d.honey()
    print d

现在,with Mgr() as d构建并初始化Mgr个实例(您没有__init__,因此无效),然后调用其__enter__返回该实例的方法,然后将结果分配给d。然后它会运行d.honey()print d。然后(无论是否存在例外)它调用d.__exit__(…)