为什么这不起作用:
class X:
var1 = 1
def __enter__(self): pass
def __exit__(self, type, value, traceback): pass
with X() as z:
print z.var1
我明白了:
print z.var1
AttributeError: 'NoneType' object has no attribute 'var1'
答案 0 :(得分:20)
将X
的定义更改为
class X(object):
var1 = 1
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
pass
with
将__enter__()
方法的返回值分配给as
之后的名称。您的__enter__()
返回了None
,已分配给z
。
我还将类更改为新式类(这对于使其工作并不重要)。
答案 1 :(得分:4)
有关上下文管理员的信息,请参阅docs:
__enter__( )
输入运行时上下文并返回此对象或 另一个与运行时相关的对象 上下文。这个值返回的值 方法绑定到标识符中 with语句的as子句使用 这个上下文经理。一个例子 返回自身的上下文管理器是 一个文件对象。文件对象返回 他们自己从__enter__()
允许open()
用作上下文 在with语句中表达。上下文管理器的一个例子 返回一个相关的对象 归来的
decimal.Context.get_manager()
。这些 经理设置有效小数 上下文到原始副本 小数上下文然后返回 复制。这允许进行更改 到当前的小数上下文 没有的声明的主体 影响以外的代码 言。
您的__enter__
方法不会返回任何内容,这与返回None
相同。
答案 2 :(得分:0)
您在'with'和'as'之间定义的函数必须具有且仅具有一个返回值。 “ with”会将值传递给其内置方法__enter__()
。
如果调用时未定义,Python中的类类型对象将不返回任何值。
类似地,如果您使用不返回任何内容的方法调用类类型的对象,它也会抛出异常。
你不能这样写:
with open('file.txt').readlines() as lines:
这会生成两个返回值,甚至不允许在Python中将其传递给一个变量。
但这很好用:
with open('file.txt') as f:
lines = f.readlines()