使用上下文管理器时,对象变为无

时间:2011-02-23 16:00:19

标签: python with-statement

为什么这不起作用:

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'

3 个答案:

答案 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()