2017-08-27 5 views
2

withセクションの終了後、以下のコードでエラーAttributeError: __exit__が表示されます。 Elementオブジェクトはwithに返されており、__exit__が定義されているので、私はうんざりです。AttributeオブジェクトのErrorErrorを受け取る:WITHオブジェクトのEXITが定義されている場合でも__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") 
+4

コードを実行すると、 '__call_'がNoneを返すので、私は__enter__のAttributeErrorを取得します。 – BrenBarn

+1

python 3.5.2の下では '__exit__'のための' AttributeError'を受け取りますが、 'python 3.6.1の' __enter__'のための 'AttributeError'を受け取りました。 '__call __()'が 'with'によって返されているものを決定し、' return self'を持つ必要があることが正しいことが分かります。ありがとう。 – markhern

答えて

0

withキーワードの後の式の値は有効なコンテキストマネージャである必要があります。それはexpresionの属性__enter____exit__を持っている必要があり、これらはドキュメントWith Statement Context Managersで説明されているパラメータを受け入れなければならないことを意味します。部分aa.feedが受け入れられることを簡単に確認できますが、式全体の値はNoneであり、必要な属性はありません。 Python 3.5と3.6の違いは、__exit__が不足して失敗し、__enter__が不足していることに後者が失敗することです。予想外のことはありません。

また、def __call__(self, *args, **kargs):の行にあるselfを忘れてしまいました。これはargsを使用する場合には問題になります。また、使用されていないargsでもpythonicパターンです。

関連する問題