3

やっていると思った

@f
def g():
   print 'hello'

とまったく同じです

def g():
   print 'hello'
g=f(g)

しかし、私はcontextlib.contextmanagerを使用するこのコードを持っていました:

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

これは機能し、1 3 2

そして私がそれをに変えようとしたとき

def f():
    print 1
    yield
    print 2
f=contextlib.contextmanager(f)
with f:
    print 3

私は得るAttributeError: 'function' object has no attribute '__exit__'

私は何が欠けていますか?特にcontextlib.contextmanagerにいくつかの黒魔術がありますか、それともデコレータが一般的にどのように機能するかを誤解していますか?

4

1 に答える 1

5

はい、デコレータは関数を呼び出して戻り値に代入するのとまったく同じです

この場合、関数を呼び出していないためにエラーが発生するため、正しいコードは次のようになります。

def f():
    print 1
    yield
    print 2

f=contextlib.contextmanager(f)
with f():
    print 3

また、コードをテストしたかどうかもわかりません。指定したデコレータ コードは同じ理由で失敗するためです。

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

エラー:

    with f:
AttributeError: 'function' object has no attribute '__exit__'
于 2010-06-19T07:30:10.287 に答える