2

ここでこのシングルトンの実装に出くわしました: http://blog.amir.rachum.com/post/21850841339/implementing-the-singleton-pattern-in-python最初の返信で。

def singleton(cls):
    return cls()

@singleton
class Foo(object):
    def bar(self):
        pass

if __name__ == '__main__':

    print id(Foo)
    print id(Foo) 

しかし、内部の仕組みがわかりません。デコレータはクラスインスタンスを返しますが、なぜ毎回同じインスタンスなのですか?

4

2 に答える 2

6

そのコードを次のように書き換えることができます

class Foo(object):
    pass

Foo = singleton(Foo)
# which is
Foo = Foo()

したがって、ここではクラスの名前がそのインスタンス化に置き換えられています。Foo.__class__特に、を使用して同じクラスの新しいオブジェクトを作成でき、命名スキーマをいじっているため、私の意見では少し安っぽいです。

于 2013-01-15T11:04:19.277 に答える
1

シングルトンは内部状態を保持することでそれを行います。ここでのこの状態は、おそらくクラスのインスタンスです。デコレータは任意のものにすることができます。

これを見てください:

http://hairysun.com/downloads/DecoratorHandout.pdf

class Decorator(object):
    # in __init__ set up state
    def __call__(self, function):
        @functools.wraps(function)
        def wrapper(*args, **kw): # 1.
            print "before func"
            result = function(*args, **kw) # 2.
            print "after func"
            return result
        return wrapper # 3.

>>> decorator2 = Decorator()
>>> @decorator2
... def nothing(): pass

デコレータは基本的に、

  1. 関数を定義します
  2. それはあなたが渡した関数を呼び出します
  3. 後で呼び出されるように、新しく「ラップされた」関数を返します

周囲のクラス (ここではデコレーター) は、次のようなことを行うことができます。

class Singleton(object):
     def __init__(self):
        self.instance = None

     def __call__(self, function):
         @functools.wraps(function)
         def wrapper(*args, **kw):
             if self.instance is None:
                self.instance = function(*args, **kw)
             return self.instance
         return wrapper

私はコードを実行しませんでしたが、これが一般的な仕組みだと思います。使用可能なインスタンスがない場合は作成します。利用可能な場合は、新しいものを作成しないでください。代わりに、古いものを 1 つ返します。これを本番環境で使用する前に、callable の他のプロパティを確認する必要があるかもしれません。

于 2013-01-15T11:11:43.353 に答える