2017-01-19 22 views
0

Python 3.5 with文の中で呼び出し可能な呼び出しができない理由や理由はありますか?ブロックされたPython内で呼び出し可能な呼び出し可能なのはなぜですか?

class Seriously(object): 
    def __init__(self, name): 
     self.name = name 

    def __enter__(self): 
     print("Enter " + self.name) 

    def __call__(self): 
     print("Call " + self.name) 

    def __exit__(self, type, value, traceback): 
     print("Exit " + self.name) 

a = Seriously('a') 
a.__enter__() 
a() 
a.__enter__() 

with Seriously('b') as b: 
    b() 

は真剣

Enter a 
Call a 
Enter a 
Enter b 
Exit b 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-6-91a5d11e1b2e> in <module>() 
    18 
    19 with Seriously('b') as b: 
---> 20  b() 

TypeError: 'NoneType' object is not callable 

私はPEP 343で何をしないのですが生成しますか?

答えて

4

__enter__メソッドから返されるものはありません。このメソッドは、PythonコンパイラによってNoneの戻り値に変換されます。 節で拘束される値を__enter__から戻すことになっています。

with文は(PEPからあなたが質問ににリンクされている)

mgr = (EXPR) 
exit = type(mgr).__exit__ 
value = type(mgr).__enter__(mgr) ### <--- usually the same as mgr.__enter__() 
exc = True 
try: 
    try: 
     VAR = value    ### <--- value returned by __enter__, VAR from with/as statement 
     BLOCK 
    except: 
     exc = False 
     if not exit(mgr, *sys.exc_info()): 
       raise 
finally: 
    if exc: 
     exit(mgr, None, None, None) 

として脱糖されます。

+0

__call__の最後に 'return self'でした。一度受け入れることができます、ありがとうございます。 –

0

__enter__メソッドは、オブジェクト(self)を明示的に返すことができ、コンストラクタはすでに__enter__の前に呼び出されています。あなたは、オブジェクトを渡すことも、変更することも、別のオブジェクトを返すこともできます。

このメソッドは、selfの4つの引数とそれに続く例外タイプ、値、およびトレースバックオブジェクトを取得します。これはsys.exc_info()と同じものです。例外がない場合、3つの例外パラメータはすべてNoneです。

__exit__Trueを返す場合、これは例外が処理されて伝播されないことを示します。戻り値がFalseの場合、例外は発生していません。

+1

'__enter__'から' self'を返すことは必須ではありません。それは要件に応じて異なります。 –

+0

@MoinuddinQuadri:はい、私は* should *の代わりに*できるはずだったはずです。私は "あなたはただオブジェクトを通過させるか、それを変更するか、別のオブジェクトを返すことができる"と言う。 – cdarke

+0

私は*必須であるので*うまくいきましたか(そうではありませんか?何もオブジェクトと一緒に使用するのは無意味です)、この回答の最初の段階では 'self'について言及する価値はありませんでした。あなたはOPの要件に合っているので、答えの後半に「self」を提案として言及することができます。 PS:ちょうど私の考え:) –

関連する問題