6

開始および停止できる Server という名前のクラスがあります。特定のメソッドは、サーバーが起動されていない限り呼び出されるべきではありません。その場合、NotConnectedException が発生する必要があります。クラス内のすべてのメソッドの前にメソッドを呼び出し、クラス変数 _started が True に設定されているかどうかを判断する方法はありますか?

デコレータを使ってみたのですが、デコレータ関数がクラス変数にアクセスできません。私はこのようなことをしようとしていました:

class Server(object):
    _started = False
    def started(self):
        if(self._started == False):
            raise NotConnectedException

    @started
    def doServerAction(self):
       ...
4

1 に答える 1

9

デコレータとは何かを覚えておいてください:

@decorate
def foo(...):
    ...

は次とまったく同じです:

def foo(...):
    ...
foo = decorate(foo)

デコレーターはfunctionで呼び出されるため、最初のパラメーターselfを呼び出しても意味がありません。また、関数の定義時にデコレーターが呼び出され、それが返すものはすべて関数の代わりに使用されます。したがって、デコレータが関数の属性にアクセスしようとして をstartedスローしなかったとしても、 が返され、すべてのメソッドが に設定され、呼び出し可能になることさえありません。AttributeError_startedNoneNone

あなたが望むのは次のようなものです:

import functools

def started(func):
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        if not self._started:
            raise ...
        else:
            return func(self, *args, **kwargs)
    return wrapper

ほとんどすべてのデコレータがこの形式です。関数を受け取り、受け取った関数の「周り」で何かを行うラッパーを作成し、ラッパーを返します。here を使用するとfunctools.wraps、対話型インタープリター セッションでこのコードを使用することになった場合に便利です。元の関数の名前とドキュメント文字列を使用して関数を自動的に更新しますwrapper。これにより、装飾された関数が元の関数に少し似たものになります。

これがクラス内で定義されているかどうかは関係ありません。

于 2012-06-05T21:41:07.627 に答える