2

Pythonでシングルトンに関するコードを見ているときに、自分でコードを書くことにしました。

これが私の最初のコードでした:

def singleton(cls):
    instance = False
    def constructor(*args,**kwargs):
        if not instance:
            instance = cls(*args,**kwargs)
        return instance
    return constructor

しかし、私がそれをテストしたとき、インタプリタは、if条件で使用される前に「インスタンス」を宣言する必要があると私に言いました、最終的に私は次のようにそれを行うことを理解しました:

def singleton(cls):
    cls._instance = False
    def constructor(*args,**kwargs):
        if not cls._instance:
            cls._instance = cls(*args,**kwargs)
        return cls._instance
    return constructor

そしてそれは期待通りに機能しました:

>>> @singleton
>>> class A: pass
>>> a=A()
>>> id(a)
33479456
>>> b=A()
>>> id(b)
33479456

最初の例のクロージャーが機能しなかった理由。

編集:エラーは

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "singleton.py", line 4, in constructor
    if not instance:
UnboundLocalError: local variable 'instance' referenced before assignment
4

2 に答える 2

3

constructor関数内でに割り当てたため、最初のクロージャーは機能しませんでしたinstance。これによりinstance、内部constructorにローカル名が作成され、割り当てられる前にそのローカル名にアクセスしました。

Python 3では、を使用nonlocal instanceしてスコープを宣言できますinstanceinstancePython 2では、必要に応じてその外部名にアクセスすることはできません。

また、シングルトンはPythonでは珍しいものです。クラスを一度だけインスタンス化してみませんか?Pythonをだまして動作を変えようとするのはなぜですか?または、使用するインスタンスを生成するファクトリ関数を作成しますか?

于 2012-04-14T23:20:35.950 に答える
0

クロージャ変数はPythonでは読み取り専用であるため、インスタンスに値を割り当てようとすると、Pythonはそれを実行できません。インスタンスが宣言されているため、エラーメッセージは少し誤解を招く可能性があります。これは、クロージャ内に書き込むことができないためです。

于 2012-04-14T23:19:02.200 に答える