0

私は現在、foo クラスのすべてのインスタンス間で共有されるだけでなく、他のクラス bar でも共有されるいくつかの変数を持ついくつかのクラス foo() を持っています。

すなわち

class foo():
    __init__(self, a, b):
        self.a = a
        self.b = b

class bar():
    __init__(self, a, b):
        self.a = a
        self.b = b

1 つの解決策は、a および b クラス変数を作成することですが、構築中にそれをきれいに行うにはどうすればよいでしょうか? 両方のクラスを同じファイルに入れて、いくつかのグローバル変数 a と b を参照させることはできますか? それは悪い習慣ですか?

4

4 に答える 4

1

あなたはこれを行うことができます:

class Foo(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

class Bar(Foo):
    pass

Foo から継承することで、Foo の構築方法も採用することになり、同じように動作します。オーバーライドする必要がある場合は、Bar で次のように設定できます。

def __init__(self, a, b, c):
    super(Bar, self).__init__(a, b)
    self.c = c

super最初に基本クラスのメソッド (この場合は Foo) を呼び出してから、必要に応じて追加できるようにします。興味があれば、ここに super のドキュメントがあります。

于 2013-06-20T21:29:08.940 に答える
1

通常の解決策は、共有情報を格納するオブジェクトを作成し、それを必要とするクラスをインスタンス化するときにそれを渡すことです。多くの場合、これはある種の構成情報であるため、クラスを呼び出します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.numberor self.config.text(など) を取得してデータにアクセスできます。

さまざまなクラスのインスタンスはすべて同じオブジェクトへの参照を保持しているため、eg adams_configorへの変更LincolnConfigは、これらのオブジェクトの 1 つへの参照を保持する任意のクラスの任意のインスタンスによって見られます。これが必要な動作でない場合は、インスタンス化時に構成オブジェクトから「凍結」したいデータを釣り上げて、インスタンスの属性として設定することができます。

さまざまな場所でアクセスしたいデータに辞書を使用することもできますが、継承と属性アクセス構文の利点は、クラスでそれを行うための良い議論だと思います.

デフォルト値として使用されるグローバル構成オブジェクトを使用することもできるため、「正常に機能する」ようにする場合は明示的に指定する必要はありません。ここではConfig、関心のある属性のデフォルト値が既にあるため、クラス自体を使用します。

class Baz(object):
    def __init__(self, config=Config):
        self.config = config

グローバル変数の代わりにこのアプローチを使用することで、オブジェクトを使用するクライアントが、すべてのインスタンスに対して設定の 1 つの「バンドル」に制限されるのではなく、異なる設定を持つ多数のインスタンスを持つことが容易になります。

于 2013-06-20T21:52:15.823 に答える
0

「建設中にきれいに」というのが何を意味するのかわかりません

次のように関数の外で定義することにより、クラス変数を使用できます。

class A:
  x = 1
  def __init__(self):
     pass

そして、変数が必要なときはいつでも、他のクラス内またはどこでも Ax を呼び出すだけです

于 2013-06-20T21:41:07.000 に答える