22

なぜこれが機能しないのですか?

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'
4

3 に答える 3

38

の定義をXに変更します

class X(object):
    var1 = 1
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        pass

withメソッドの戻り値を。__enter__()の後の名前に割り当てasます。に割り当てられたあなたの__enter__()返品。Nonez

また、クラスを新しいスタイルのクラスに変更しました(これを機能させるために重要ではありません)。

于 2011-02-23T16:04:09.203 に答える
7

コンテキストマネージャのドキュメントを参照してください。

__enter__( )ランタイムコンテキストを入力し、このオブジェクトまたはランタイムコンテキストに関連する別のオブジェクトを返します。このメソッドによって返される値は、このコンテキストマネージャーを使用してwithステートメントのas句の識別子にバインドされます。自分自身を返すコンテキストマネージャーの例は、ファイルオブジェクトです。ファイルオブジェクトはから戻り、withステートメントのコンテキスト式として使用__enter__()できるよう にします。open()

関連オブジェクトを返すコンテキストマネージャーの例は、によって返されるもの decimal.Context.get_manager()です。これらのマネージャーは、アクティブな10進コンテキストを元の10進コンテキストのコピーに設定してから、そのコピーを返します。これにより、withステートメントの外部のコードに影響を与えることなく、withステートメントの本体の現在の10進コンテキストに変更を加えることができます。

メソッドは何も返しませ__enter__ん。これは、を返すのと同じNoneです。

于 2011-02-23T16:06:01.913 に答える
2

'with'と'as'の間に定義した関数は、戻り値が1つだけである必要があります。'with'は、その値を組み込みメソッドに渡します__enter__()

Pythonのクラス型オブジェクトは、呼び出し時に定義されていない場合、値を返しません。

同様に、何も返さないメソッドを使用してクラス型オブジェクトを呼び出すと、例外もスローされます。

あなたはこのように書くことはできません:

with open('file.txt').readlines() as lines:

これにより2つの戻り値が生成され、Pythonでは1つの変数に渡すこともできません。

しかし、これは使用するのに適しています。

with open('file.txt') as f:
    lines = f.readlines()
于 2019-07-24T01:32:01.630 に答える