4

重複の可能性:
Pythonのスーパークラスのinitメソッドが自動的に呼び出されないのはなぜですか?

例えば:

class Pet(object):

    def __init__(self, name, species):
       self.name = name
       self.species = species

    def getName(self):
     return self.name

    def getSpecies(self):
     return self.species

    def __str__(self):
     return "%s is a %s" % (self.name, self.species)

class Dog(Pet):

   def __init__(self, name, chases_cats):
      Pet.__init__(self, name, "Dog")
      self.chases_cats = chases_cats

   def chasesCats(self):
     return self.chases_cats

ご覧のとおり、犬はペットから受け継いでいます。私はコードを完全に理解しています。しかし、なぜ犬のクラスでペットのinitを呼び出す必要があるのでしょうか。犬のクラスの最初の行(class Dog(Pet))のように単にそれを呼び出さないのはなぜですか?厄介なコードしか作成されていないようです。それは私にとってPythonの継承のポイントを殺してしまいます。

4

2 に答える 2

9

言語が強制的にスーパークラスを初期化する前または後に初期化すると、機能が失われます。サブクラスは、最初に実行されるスーパークラスの初期化に依存する場合もあれば、その逆の場合もあります。

さらに、どの引数を渡すかを知る方法がありません。サブクラスは、初期化子に渡す値を決定します。これにより、すべての引数を自動的に渡すよりも柔軟性が高くなります。

スーパークラスを初期化する別の方法は super を使用することですが、これは実際にはオブジェクトの(メソッド解決順序)selfで検索することにより、スーパークラスを動的に初期化します。__mro__

Python 2 の場合:

super(self, Dog).__init__(self, name, "Dog")

Python 3 では、構文をさらに減らして、同じことを繰り返さないようにすることができます。

super().__init__(self, name, "Dog")

編集

実際にはnamedog に渡された引数を使用していないため、初期化子で任意のキーワードと位置引数を受け入れ、Dogそれらを初期化チェーンに渡すことで、いくつかの構文をさらに減らすことができます。

class Dog(Pet):

   def __init__(self, chases_cats, *args, **kwargs):
      Pet.__init__(self, *args, species="Dog", **kwargs)
      self.chases_cats = chases_cats

class Pet(object):

    def __init__(self, name, species, *args, **kwargs):
       self.name = name
       self.species = species

あなたのシナリオでは、初期化子はこれを必要としないほど単純かもしれませんが、引数が増えたり、クラス階層が深くなったりする場合に備えて知っておくと便利です。

于 2012-05-09T03:14:58.550 に答える
4

このように種をクラス属性にすることができます

class Pet(object):
    species = None

    def __init__(self, name):
        self.name = name

    def getName(self):
        return self.name

    def getSpecies(self):
        return self.species

    def __str__(self):
        return "%s is a %s" % (self.name, self.species)

class Dog(Pet):
    species = "Dog"

    def __init__(self, name, chases_cats):
        Pet.__init__(self, name)
        self.chases_cats = chases_cats

    def chasesCats(self):
        return self.chases_cats
于 2012-05-09T03:31:07.520 に答える