通常の解決策は、共有情報を格納するオブジェクトを作成し、それを必要とするクラスをインスタンス化するときにそれを渡すことです。多くの場合、これはある種の構成情報であるため、クラスを呼び出しますConfig
。
class Config(object):
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
# default values
number = 0
text = "Nothing"
Python はダック型であるため、任意のオブジェクトを使用してこの構成を保持できます。クラスのインスタンスまたはクラス自体にすることができます。前者は、実行時にデータを指定する場合に便利です。後者は、プログラマーがコーディング時に継承を使用して属性のさまざまなバンドルを定義できるため便利です。ここでのConfig
クラスでは、どちらの方法でも使用できます。インスタンス化してキーワード引数に共有値を渡すか、サブクラス化して共有値をクラス属性として提供できます。
Foo
およびBar
クラスでは、コンストラクターで共有データを受け入れるだけです。
# these classes both need certain pieces of data
# but are not related by inheritance
class Foo(object):
def __init__(self, shared):
self.shared = shared
class Bar(object):
def __init__(self, config):
self.config = config
次に、クラスをインスタンス化するかConfig
、サブクラスを定義して、結果のオブジェクトを新しいオブジェクトに渡します。
# use an instance
adams_config = Config(text="Don't Panic", number=42)
foo1, bar1 = Foo(adams_config), Bar(adams_config)
# use a subclass
class LincolnConfig(Config):
number = 87
text = "Four score and seven years ago"
foo2, bar2 = Foo(LincolnConfig), Bar(LincolnConfig)
Foo
これで、Bar
クラスのメソッドはself.shared.number
or self.config.text
(など) を取得してデータにアクセスできます。
さまざまなクラスのインスタンスはすべて同じオブジェクトへの参照を保持しているため、eg adams_config
orへの変更LincolnConfig
は、これらのオブジェクトの 1 つへの参照を保持する任意のクラスの任意のインスタンスによって見られます。これが必要な動作でない場合は、インスタンス化時に構成オブジェクトから「凍結」したいデータを釣り上げて、インスタンスの属性として設定することができます。
さまざまな場所でアクセスしたいデータに辞書を使用することもできますが、継承と属性アクセス構文の利点は、クラスでそれを行うための良い議論だと思います.
デフォルト値として使用されるグローバル構成オブジェクトを使用することもできるため、「正常に機能する」ようにする場合は明示的に指定する必要はありません。ここではConfig
、関心のある属性のデフォルト値が既にあるため、クラス自体を使用します。
class Baz(object):
def __init__(self, config=Config):
self.config = config
グローバル変数の代わりにこのアプローチを使用することで、オブジェクトを使用するクライアントが、すべてのインスタンスに対して設定の 1 つの「バンドル」に制限されるのではなく、異なる設定を持つ多数のインスタンスを持つことが容易になります。