web-dev-qa-db-ja.com

Pythonインスタンスが1つだけのクラス:(単一の)クラスインスタンスを作成する場合と、代わりにクラスを使用する場合?

Pythonクラスは1回だけインスタンス化されます。つまり、クラスのオブジェクトは1つしかありません。この場合、直接作業するのではなく、単一のクラスインスタンスを作成するのが理にかなっていると思いました。代わりにクラスで。

同様の question がありますが、フォーカスが異なります。

  1. グローバル変数と関数をクラスにグループ化し、
  2. Python固有ではありません。後者は、(Pythonでは)クラスもオブジェクトであるという事実を考慮しないことを意味します。

UPDATE:

Pythonでは、クラスとオブジェクトの両方で次のことができます。

class A(object):
    pass

A.some_state_var = True
# Then later
A.some_state_var = False


my_a = A()

my_a.some_state_var = True
# Then later
my_a.some_state_var = False

したがって、クラスとそのクラスのインスタンスの間の選択がどのように(Pythonで)状態になるかはわかりません。どちらでも状態は維持できます。

さらに、クラス/クラスインスタンスを作成する動機は、シングルトン要件を強制することではありません。

また、新しいTypeを作成することもそれほど重要ではありません。

動機は、関連するコードとデータをグループ化し、それらへのインターフェースを持つことです。これが、最初にクラス図のクラスとしてモデル化した理由です。実装に関してのみ、このクラスをインスタンス化するかどうか疑問に思い始めました。

11
langlauf.io

Pythonクラスは1回だけインスタンス化されます。つまり、クラスのオブジェクトは1つしかありません。この場合、直接作業するのではなく、単一のクラスインスタンスを作成するのが理にかなっていると思いました。代わりにクラスで。

それでこれは:

class Singleton:
    '''don't bother instantiating me'''
    clsvar1 = 'foo'

    @classmethod
    def foobar(cls, *args, **kwargs):
        if condition():
            cls.clsvar1 = 'bar'

これに対して?

class Singleton:
    '''instantiate and use me'''
    def __init__(self):
        self.var1 = 'foo'

    def foobar(self, *args, **kwargs):
        if condition():
            self.var1 = 'bar'

推奨

私は間違いなくインスタンス化することを意図したものを好みます。 「もののタイプ」を作成するとき、そのタイプのものを作成することを意味します。

動機は、関連するコードとデータをグループ化し、それらへのインターフェースを持つことです。

そうは言っても、必要なのは名前空間だけなので、なぜモジュールを使用しないのですか?モジュールはシングルトンであり、グループに関連するコードとデータであり、これは少し単純で、おそらくよりPythonicと見なされます。

var1 ='foo'

def foobar(*args, **kwargs):
    global var1
    if condition():
        var1 = 'bar'

したがって、使用法は次の代わりになります。

from modules.singleton import Singleton
Singleton.foobar()

または

from modules.singleton import Singleton
the_singleton = Singleton()
the_singleton.foobar()

これを行う:

from modules import singleton
singleton.foobar()
16
Aaron Hall

代わりにクラスを直接操作するのではなく、単一のクラスインスタンスを作成するのが理にかなっているのではないかと思っていました。

これは、宗教戦争に巻き込まれた場合に宗教戦争を引き起こすものの1つです。

しかし、一般に、私が何度も見た慣習では、クラスメソッドは、そのクラスのインスタンスの作成のみに関係するべきです。

クラスとは何か、その目的/動作は何かと考えると、これは理にかなっています。 クラスの目的は、それ自体に基づくオブジェクトのインスタンスを作成することです。建物を建てることもできる青写真です。 「ユーザー」クラスは「ユーザー」オブジェクトを作成します。 「犬」クラスは「犬」オブジェクトなどを作成します

これがクラスの振る舞いであり、クラス "X"に追加するメソッドが "x"オブジェクトの作成に関与することは理にかなっています。

したがって、「x」オブジェクトが1つだけ必要になる場合でも、インスタンス化する必要があります。

「x」オブジェクトのインスタンスの作成に関連しないメソッドをXクラスに追加すると、予期しないコードが混乱する可能性があります。もちろん現実の世界では、とにかく人がこれをした例がたくさんありますが、私が言ったように、その道は宗教戦争につながります。

2
Cormac Mulhall