2017-05-19 5 views
1

継承されたクラスの複数のインスタンス化を防ぎたいと思います。シングルトンのパターンはこの作業には適切だと思われましたが、私が期待した結果は得られません。シングルトンクラスを拡張するクラスの初期化を防止する

これは私のコード例である:これを実行

class Singleton(type): 
    _instances = {} 

    def __call__(cls, *args, **kwargs): 
     if cls not in cls._instances: 
      cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) 
     return cls._instances[cls] 


class Config(metaclass=Singleton): 
    def __init__(self): 
     print('initialized') 


class DevelopConfig(Config): 
    pass 


class TestingConfig(Config): 
    pass 


foo = DevelopConfig() 
bar = TestingConfig() 

が、私は単一の出力として「初期化」を参照してくださいことを期待するが、それは二回表示されます。どのようにこれらのクラスの複数のインスタンスを防ぐためのアイデア?私は何を取りこぼしたか?

編集:最終的な目標は、複数の同時設定を防止することです。よりスマートな方法があれば、私はそれを聞くのが大好きです。

答えて

1

あなたが経験していることの背後にある主な問題は、clsです。実際にあなたが考えるものではありません。変数がclsと呼ばれているからといって、それがクラスオブジェクトであることを意味するものではなく、実際にはselfというオブジェクトです。

あなたがシングルトンクラスにprintステートメントを追加した場合これは見ることができます。

class Singleton(type): 
    _instances = {} 
    def __call__(cls, *args, **kwargs): 
     print(cls) 
     #etc... 


>>> foo = DevelopConfig() 
<class '__main__.DevelopConfig'> 
initialized 
>>> bar = TestingConfig() 
<class '__main__.TestingConfig'> 
initialized 

インスタンスは として「と呼ばれる」されたときに呼び出されdocs

object.__call__(self[, args...])

からに機能;このメソッドが定義されている場合、x(arg1, arg2, ...)は、x.__call__(arg1, arg2, ...)の略語 です。


私は辞書をドロップすることをお勧めしますが、インスタンスが1つだけ存在する場合、あなたはそれを必要はありません。これは問題を単純化します。

class Singleton(type): 
    _instance = None 
    def __call__(self, *args, **kwargs): 
     if not Singleton._instance: 
      Singleton._instance = super(Singleton, self).__call__(*args, **kwargs) 
     return Singleton._instance 

class Config(metaclass=Singleton): 
    def __init__(self): 
     print('initialized') 


class DevelopConfig(Config): 
    pass 


class TestingConfig(Config): 
    pass 

これが生成します。

>>> foo = DevelopConfig() 
initialized 
>>> bar = TestingConfig() 

>>> foo 
<__main__.DevelopConfig object at 0x00000259CE2FD080> 
>>> bar 
<__main__.DevelopConfig object at 0x00000259CE2FD080> 
>>> 
+0

感謝を。完璧な答え。 :) – sonovice

関連する問題