0

この質問に適切なタイトルを付けなかったことをお詫びします。投稿する理由は、探しているものを知るための正しい用語さえ持っていないからです。

属性「スパム」を持つクラスを定義しました。

def SpamClass(オブジェクト):
    def __init__(自己、引数):
        self.spam = 引数
    def __str__(自己):
        self.spam を返す

まったく同じ機能を持つ (サブ/兄弟?) クラスを作成したいのですが、「spam」ではなく「eggs」という名前の属性を使用します。

def EggsClass(オブジェクト):
    def __init__(自己、引数):
        self.eggs = 引数
    def __str__(自己):
        self.eggs を返す

一般化すると、機能的に同一のクラスを任意の属性名で作成するにはどうすればよいですか? クラスの動作が複雑な場合、コードを複製するのはばかげているように思えます。

更新:これは悪いデザインの匂いがすることに同意します。明確にするために、私はこのばかげた方法で特定の問題を解決しようとしているわけではありません。__dict__機能を維持しながら、オブジェクトの (非魔法の) コンテンツに任意に名前を付ける方法を知りたいだけです。keys()のようなオブジェクトのメソッドのようなものを検討してくださいdict。人々は慣習に従って動作するメソッドを使用してさまざまなクラスを作成しますkeys()が、命名規則は良いことです。しかし、名前は任意です。ソース内の /keys/spam/ を手動で置換せずspam()に正確に置換するメソッドでクラスを作成するにはどうすればよいですか?keys()

ジェネリック属性を参照するためのオーバーロード__getattr__と友人は、私にはエレガントで壊れやすいようです。サブクラスがこれらのメソッドを再実装する場合、この動作に対応する必要があります。単純にアクセスできる名前付き属性を持つ単純な基本クラスがあることをユーザーに見せたいと思います。

実際、もっともらしいユースケースを思いつくことができます。特別な属性を付与する mixin クラスと、この属性を操作または依存するいくつかの密接に関連したメソッドが必要であるとします。ユーザーは、この特別な属性にクラスごとに異なる名前を付けたい場合があります (実際の問題領域で名前を一致させるため、または名前の衝突を避けるため)、基礎となる動作を再利用します。

4

4 に答える 4

4

これが、あなたが望むと思う効果を得る方法です。

ジェネリック属性名を持つジェネリック クラスを定義します。次に、各サブクラスでhttp://docs.python.org/reference/datamodel.html#customizing-attribute-accessのアドバイスに従って、属性を外部から見た場合は、任意の名前で呼び出されるようにします。

何をするかについてのあなたの説明は、私には「コードの匂い」があるように感じます。これが本当にあなたがやりたいことかどうかを確認するために、あなたのデザインを非常に注意深く見直すことをお勧めします. しかし、あなたは私の提案でそれを機能させることができます。

于 2011-02-11T07:32:18.887 に答える
1

すべての一般的なものを含むスーパークラスを作成してから、特定の属性を含むサブクラスを作成することもできます。

あるいは:

def SuperClass(object):
    specific_attribute = 'unset'

    def __init__(self, arg):
        setattr(self, specific_attribute, arg)

    def __str__(self):
        return getattr(self, specific_attribute)


def EggClass(SuperClass):
    specific_attribute = 'eggs'
于 2011-02-11T07:50:05.317 に答える
1

物事を過度に複雑にせず、ただ 1 つのクラスを作成することを検討しましたか? (とにかく同じなので)

class FoodClass(object):
    def __init__(self, foodname, arg):
        self.attrs = {foodname: arg}
        self.foodname = foodname

    def __str__(self):
        return self.attrs[foodname]

素敵なコンストラクターが必要な場合は、個別に作成してください。

def make_eggs(arg):
    return FoodClass('eggs', arg)

def make_spam(arg):
    return FoodClass('spam', arg)
于 2011-02-11T08:46:27.010 に答える
0

実行時に属性を作成するにはself.__dict__['foo'] = 'I'm foo'、それらをクラス コードに追加するだけです。

于 2011-02-11T08:52:31.393 に答える