嘿,伙计们是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__
答案 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
。 (有些用例可能有意义,但一般情况下不一样。)
或者,没有理由b
和b.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__(…)
。