0

現在のシナリオ:

コンストラクターですべて共通の引数を取る一連のクラスがありcontext、すべてのクラスは共通のベースから継承します。

class base:
    def common_method(self):
        pass

class a(base):
    def __init__(self,context, aa):
        pass

class b(base):
    def __init__(self, context, bb):
        pass

# ...

class z(base):
    def __init__(self, context, zz):
        pass

メインでの使用法:

context = get_context_from_some_method()

A = a(context, 1)
B = b(context, 2)
C = c(context, 3)
D = d(context, 4)
.
.
.
Z = z(context, 26)

問題:

  • contextすべてのクラスに暗黙的に提供するトリッキーな方法はありますか?
  • 共通の基本クラスがありますが、すべてのクラスのコンテキストを設定できる明確な方法がわかりません。
  • すべてのクラス インスタンスに共通のコンテキストを維持したいと考えられます。
  • ただのランダムな考え - メタクラスは何とか役立つでしょうか?

ばかげているように思えることはわかっていますが、何らかの方法で冗長性を取り除き、何らかの方法でグローバル コンテキストを設定し、オブジェクトに集中できるようにしたいだけです。

何らかの方法を提案してください。

**質問への更新**

これはWebアプリケーションで使用されるため、基本クラスにコンテキストを設定できません。したがって、コンテキストが異なる多くのページがクラス構造を使用します。したがって、ベースにコンテキストを設定すると、同じベースを使用する Web ページの別のインスタンスによって設定されるコンテキストと競合します。Web アプリケーションでは、上記のすべてのクラスがすべてのページに共通のメモリ内にあるためです。

4

4 に答える 4

2

編集:クラス変数を使用したくない/使用できない場合は、ファクトリ関数を使用することをお勧めします。基本クラスの静的メソッドにするか、モジュール レベルの関数にします。

def make_instances(context, *instances):
    return [cls(context, *args) for cls, args in instances]

A, B, ..., Z = make_instances(get_context_from_some_method(), 
                 (a, (1,)), (b, (2,)), ..., (z, (26,)))

# or
instances = make_instances(get_context_from_some_method(), 
             zip(list_of_subclasses, ((x,) for x in range(1, 27))))

または、これがあなたの状況で機能するかどうかはわかりませんが、モジュールレベルのグローバル変数を使用してください。

class z(base):
    def __init__(self, zz):
        self.zz = zz
        self.context = context

context = 'abc'
Z = z(26)

他の回答からクラス変数を使用するというアドバイスに加えて、コンテキストをインスタンスにコピーすることをお勧めします。これにより、既に作成されたインスタンスに影響を与えずに後でコンテキストを変更できます。

class base:
    context = None # if you want to be able to create without context.
    # just omit the previous line if you want an error
    # when you haven't set a context and you try to instantiate a subclass

class a(base):
    def __init__(self, aa):
        self.aa = aa
        self.context = self.context # sets an instance variable
        # so the class variable can be changed

class b(base):
    def __init__(self, bb):
        self.bb = bb
        self.context = self.context

base.context = 'context'

A = a(1)
B = b(2)

base.context = 'newcontext'

print A.context # context
于 2012-03-22T02:21:50.673 に答える
1

クラス変数を使用できます。

base.context = 'context'
A = a(1)
B = b(2)
#...
于 2012-03-22T02:17:12.857 に答える
-1

冗長性を排除する方法は、繰り返されるパターンを識別し、パターンをいくつかの別個のコードに分解することです。

それが実際のコードであるかどうかはわかりませんが、例からすると、同様の方法で多数のクラスをインスタンス化するというパターンがあります。入力に必要な各行から9文字を削除した場合でも、次のことcontext,を実行しています。

A = a(1)
B = b(2)
C = c(3)
...

それは私を狂わせるでしょう。冗長性の問題はタイピングではありませんが、これを変更する場合(たとえば、0から開始する場合、または各クラスに引数を追加する場合など)、すべての行を変更する必要があります。 。

だから私はむしろこのようなことをしたいと思います:

classes = [a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
instances = [cls(context, i) for i, cls in enumerate(classes, 1)]

ここに、たくさんのクラスをインスタンス化していること、および1からクラスの数までの整数(クラスごとに増加)とともに、各クラスにコンテキストを渡していることを明確に示すコードがあります。そして、クラスのリストが何であるか、または私が各クラスに渡すものを変更することを独立して決定するのは簡単です。

これは、私のインスタンスがandの代わりにandのような名前を持っていることをinstances[0]意味instances[13]AますN。それを回避する方法もありますが、物のコレクションをインスタンス化して、コレクションとしてではなく、独立した個別の物として使用することはめったにありません。

于 2012-03-22T02:45:09.143 に答える
-2

contextをbaseのクラス属性として定義する必要があります。例を変更すると、次のようになります。

class base:

    context = None

    def common_method(self):
        pass

class A(base):
    def __init__(self, aa):
        pass

class B(base):
    def __init__(self, bb):
       pass

.
.
.

class Z(base):
    def __init__(self, zz):
        pass

base.context = get_context_from_some_method()
A = a(1)
B = b(2)
Z = z(3)    

すべての A、B、および Z インスタンスは、同じコンテキストプロパティを共有します。

于 2012-03-22T02:20:48.073 に答える