2

Python クラス ( ) にラップされた機能がいくつかありますclassaclassa別のクラスから継承しsuperaます。

classaから継承することを除いて、 とまったく同じ機能が必要ですsuperb

classaクラスを新しいクラスにコピーしてからclassbスーパークラスを変更することもできますclassbが、明らかにこれは非常に粘着性があり、メンテナンスの頭痛の種であり、はるかに良い方法があると確信しています-誰かがそれが何であるか教えてもらえますか?


編集:これまでの回答に感謝します。classaメソッドを呼び出すために、メソッド内で my invokes super を最初に言うべきsuperaでした。ミックスインをオプションとして見ると、これはいくつかの重要性を持っているようです

4

1 に答える 1

4

どのメソッドも を呼び出す必要がない場合、これは Python の多重継承で行うことができますsuper()

class Dog(object):
    name = "Spot"

class Cat(object):
    name = "Whiskers"

class SpeakingAnimalMixin(object):
    def speak(self):
        print "My name is", self.name, "and I can speak!"

class SpeakingDog(SpeakingAnimalMixin, Dog):
    pass

class SpeakingCat(SpeakingAnimalMixin, Cat):
    pass

SpeakingDog().speak()

私の名前はスポットです。話すことができます。


メソッドから呼び出す必要がある場合はsuper()、クラスを動的に作成する必要があります。これは問題なく機能しますが、生成されたクラスの名前はあまり役に立たず、IDE やその他の静的分析ツールはあまり役に立たない可能性があります。

関数を使用してクラスを作成し、スーパークラスを引数として渡すことができます。

def make_speaking_animal_class(SpeechlessAnimal):
    class SpeakingAnimal(SpeechlessAnimal):
        def get_name(self):
            return "Speaking " + super(SpeakingAnimal, self).get_name()

        def speak(self):
            print "My name is", self.get_name()

    return SpeakingAnimal

class Dog(object):
    def get_name(self):
        return "Spot"

class Cat(object):
    def get_name(self):
        return "Whiskers"

SpeakingDog = make_speaking_animal_class(Dog)
SpeakingCat = make_speaking_animal_class(Cat)

SpeakingCat().speak()

私の名前は話すひげです

ただし、前述のように、クラスの__name__属性は期待どおりではない場合があります。

print SpeakingDog
print SpeakingDog()
<class '__main__.SpeakingAnimal'>
<__main__.SpeakingAnimal object at 0x1004a3b50>

__name__これは、一意の属性を自分で割り当てることで修正できます。

SpeakingDog.__name__ = 'SpeakingDog'
print SpeakingDog
<class '__main__.SpeakingDog'>

(回答でこれを提案したAndrew Jaffeの功績ですが、彼はそれを削除しました。)

クラスを動的に作成する別の方法がありますが、必要でない限り使用しないことをお勧めします。それはさらに明確ではありません。このtype関数には、オブジェクトのクラスを決定するという主な用途とは別に、2 つ目の用途があります。新しいクラスを動的に作成するために使用できます。

このように使用すると、type関数は次の 3 つのパラメーターを受け取ります。

  • name__name__新しいクラスが持つことになります。
  • bases、新しいクラスが継承する基本クラスのタプル。
  • dict、新しいクラスが持つメソッドと属性を含む辞書。

次のように使用できます。

def make_speaking_animal_class(SpeechlessAnimal, name):
    def get_name(self):
        return "Speaking " + super(SpeakingAnimal, self).get_name()

    def speak(self):
        print "My name is", self.get_name()

    bases = (SpeechlessAnimal,)

    # We need to define SpeakingAnimal in a variable so that get_name can refer
    # to it for the super() call, otherwise we could just return it directly.
    SpeakingAnimal = type(name, bases, {
        'get_name': get_name,
        'speak': speak
    })

    return SpeakingAnimal

class Dog(object):
    def get_name(self):
        return "Spot"

class Cat(object):
    def get_name(self):
        return "Whiskers"

SpeakingDog = make_speaking_animal_class(Dog, 'SpeakingDog')
SpeakingCat = make_speaking_animal_class(Cat, 'SpeakingCat')

SpeakingDog().speak()
SpeakingCat().speak()

僕の名前はスピーキングスポット
僕の名前はスピーキングウィスカーズ

于 2013-04-16T01:39:12.490 に答える