3

このシングルトン メタクラスを定義しました。

class Singleton(type):
    """Metaclass which implements the singleton pattern"""

    _instances = {}

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

ここで、すべてが正常に機能するかどうかをテストしたいと思います。これが私が試したことです:

  • 同じクラス (Singletonメタクラスとして持つクラス) の 2 つのオブジェクトを作成しました - それらのid()一致
  • 1 つのオブジェクトを作成し、それを 2 番目の変数に割り当てました - それらのid()一致
  • モジュールをインポートcopyし、最初のオブジェクトをコピーしましたcopy.copy()-それらid()は現在一致しません

コピーされたオブジェクトの ID が元のオブジェクトと一致しない理由を知りたいです。シングルトンなので、2 つのオブジェクトが同じ ID を持つべきではありませんか?

4

1 に答える 1

5

copyモジュールは新しいインスタンスを作成しませ。代わりに、空のクラスを作成し、__class__そのオブジェクトを再割り当てして、元のメソッドまたはメソッドを明確に回避します。__new____init__

__copy__代わりに、インスタンスを変更せずに返すカスタム フックを提供する必要があります。

class Singleton(type):
    """Metaclass which implements the singleton pattern"""

    _instances = {}

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

    def __copy__(cls, instance):
        return instance

copy__copy__クラスでメソッドを直接検索します。代わりにmetaclassで見つかり__copy__、クラスを検索するとバインドされたメソッドが返され、copy(バインドされていないメソッドを期待して) インスタンスが明示的に渡されます。これは、 に2 つの引数が渡されることを意味し__copy__ます。1 つ目はクラス (メタクラスのインスタンス) で、2 つ目はそのクラスのインスタンス (self従来のメソッド) です。

残念ながら、__deepcopy__代わりにインスタンスが検索され、メタクラス メソッドが見つかりません。

于 2013-09-18T11:34:07.203 に答える