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


11

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

同様の質問がありますが、焦点は異なります。

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

更新:

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を作成することはそれほど重要ではありません。

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

回答:


16

1回だけインスタンス化されるPythonクラスがある場合、つまり、クラスのオブジェクトは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()

3
ご回答有難うございます。すべての関数(変数を含む)に対して新しいモジュール(新しい.pyファイル)を作成することを本当にお勧めしますか?これにより、多くの小さな.pyファイルが作成される可能性があります。または、すべての(少なくとも何らかの関係がある)「クラスレス」関数と変数を1つのモジュールにグループ化しますか?
langlauf.io

もう1つの発言:「必要なのは名前空間だけだから」と書きます。私が欲しいのは、関連するコード、つまり関数とデータを1か所にグループ化し、それへのインターフェースを持つことです。「タイプ」を作成することではありません。設計中、とにかくクラスダイアグラム内のクラスになりますか?
langlauf.io

2

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

これは宗教的な戦争を引き起こすものの1つです。

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

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

これをクラスの振る舞いにすると、クラス「X」に追加するメソッドは「x」オブジェクトの作成に関係することになります。

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.