4

次のクラス編成への「pythonic」アプローチを見つけるのに苦労しています。

コンストラクターでプロパティが初期化された基本クラスがあります。次に例を示します。

class Animal(object):
    def __init__(self, class_, species, is_domesticated):
        self.class_ = class_
        self.species = species
        self.is_domesticated = is_domesticated

次に、サブクラス化するときに、次のように、これらのプロパティの1つ以上を「ハードコーディング」したいと思います。

class Mammal(Animal):
    def __init__(self, species, is_domesticated):
        Animal.__init__(self, 'Mammal', species, is_domesticated)

したがって、哺乳類は次のようにインスタンス化されます。

monkey = Mammal('Primate', false)

問題は、基本クラスの定義を変更するときに派生クラスをそのままにしておくために*argsを使用したいということです。したがって、哺乳類の定義は次のようになります。

class Mammal(Animal):
    def __init__(self, *args):
        Animal.__init(self, *(args + (class_='Mammal',)))

これは(言うまでもなく)恐ろしいように見えます。いくつかのヒントをいただければ幸いです=)

4

2 に答える 2

6

基本クラスに固定の引数セットしかない場合は、可変引数について心配する必要はあまりありません。最初の例で行ったことを実行するだけで問題ありません。基本クラスにランダムに引数を追加できるようにしたいが、それらを位置引数としてデフォルトなしで追加したい場合、希望はありません。基本クラスをウィリーニリーに変更して、すべての派生クラスが機能し続けることを期待することはできません。

ただし、属性のセットが大きく、そのさまざまな組み合わせが階層内の任意のクラスに渡される可能性がある、かなり一般的な中間のケースがあります。基本クラスに新しい引数を追加することもできますが、派生クラスがそれらについて明示的に知る必要がないように、デフォルトがあります。それらは、基本クラスのデフォルトに優雅に低下します。このような場合は、通常、を使用する**kwargsよりも使用することをお勧めします*args

class Animal(object):
    def __init__(self, **kwargs):
        self.class_ = kwargs['class_']
        self.species = kwargs['species']
        # etc.
class Mammal(Animal):
    def __init__(self, **kwargs):
        Animal.__init__(self, class_="Mammal", **kwargs)

これには、キーワードで渡される引数が必要です。

>>> Animal(class_='Fish', species='barracuda', is_domesticated=False)
4: <__main__.Animal object at 0x0177ABF0>
>>> Mammal(species="monkey", is_domesticated=False)
5: <__main__.Mammal object at 0x0177AFB0>

。。。しかし、それらがたくさんある場合、これはより良いです。なぜなら、10の異なるものが位置的に渡される場合、誰もそれらを渡す順序を覚えていないからです。また、新しい引数を簡単に追加できることも意味します。新しいものをリストのどこに置くかを知る必要はありません。キーワードでどこにでも追加できます。

Python 2では、上記のように手動でkwargsを抽出する必要があります。Python 3では、キーワードのみの引数を使用して、これをさらに簡単にすることができます。

于 2012-09-11T20:19:14.327 に答える
0

さて、あなたはあなたが望むと言ったことをただやってみませんか?議論をして、それを使ってMammal.__init__()ください。*argsコードは次のとおりです。

class Animal(object):
    def __init__(self, class_, species, is_domesticated):
        self.class_ = class_
        self.species = species
        self.is_domesticated = is_domesticated
    def __str__(self):
        s_dom = "dom" if self.is_domesticated else "wild"
        return ("Animal(%s, %s, %s)" % (self.class_, self.species, s_dom))

class Mammal(Animal):
    def __init__(self, *args):
        Animal.__init__(self, 'Mammal', *args)

cat = Mammal("cat", True)
print(cat)

lion = Mammal("lion", False)
print(lion)

出力:

Animal(Mammal, cat, dom)
Animal(Mammal, lion, wild)
于 2012-09-11T20:43:29.657 に答える