即使WITH对象已定义EXIT,也会收到AttributeError:__ exit__

时间:2017-08-27 02:40:36

标签: python python-3.x

完成AttributeError: __exit__部分后,我在下面的代码中收到with错误。 Element对象已在with中返回,并且已定义__exit__,因此我感到困惑。

class Builder:
    def __init__(self):
        print("Builder init fires")

    def __getattr__(self, name):
        return Element(name, self)

class Element:
    def __init__(self, name, builder):
        self.name = name
        self.builder = builder
        print("Element init fires for name of", self.name)
    def __call__(*args, **kargs):
        print("CALL fires, now with attributes listed:")
        for attr, value in sorted(kargs.items()):
            print(' %s=>%s' % (attr, value))

    def __enter__(self):  
        return self

    def __exit__(self, type, value, traceback): 
        pass

aa = Builder()        
with aa.feed(xmlns='http://www.w3.org/2005/Atom'):
    print("INSIDE THE WITH")

1 个答案:

答案 0 :(得分:1)

with关键字后面的表达式值必须是有效的上下文管理器。这意味着表达式的必须包含 __enter__ __exit__ 属性,并且这些属性必须接受docs中描述的参数With Statement Context Managers。您可以轻松验证部件aa.feed是否可以接受,但整个表达式的值为None,并且没有必要的属性。 Python 3.5和3.6之间的区别在于,一个在失去__exit__时失败而后者在失去__enter__时失败。没什么意外的。

你还忘记self行中def __call__(self, *args, **kargs):如果你使用args就会出现问题,而且它也是一个pythonic模式,还有未使用过的args。