python - 除了父类(super class)之外,两个相同的 Python 类 - 如何避免重复?

标签 python oop inheritance

我有一些功能包含在 Python 类 (classa) 中。 classa 继承自另一个类supera

我想要与 classa 完全相同的功能,只是我想从 superb 继承。

我可以将类classa复制到一个新的类classb,然后更改classb的父类(super class),但显然这非常俗气,a维护令人头疼,而且我很确定有更好的方法 - 谁能告诉我它是什么?


编辑:感谢迄今为止的答复。我应该说最初我的 classa 在其方法中调用 super 以便调用 supera 方法。当将 mixin 作为一种选择时,这似乎具有一定的意义

最佳答案

如果没有方法需要调用 super(),则可以使用 Python 的多重继承来完成此操作。

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()

My name is Spot and I can speak!


如果您确实需要从方法中调用super(),那么您需要动态创建该类。这工作得很好,但是生成的类的名称将不太有用,并且 IDE 和其他静态分析工具可能不太有用。

您可以使用函数创建类,并将父类(super class)作为参数传递:

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()

My name is Speaking Whiskers

但是如上所述,该类的 __name__ 属性可能不是您所期望的。

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

您可以通过自己为它们分配唯一的 __name__ 属性来解决此问题:

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

(归功于 Andrew Jaffe 在答案中提出了这一点,但他删除了它。)

还有另一种动态创建类的方法,但我不鼓励您使用它,除非您需要;更不清楚的是。 The type function除了确定对象的类的主要用途之外,还有第二种用途:它可用于动态创建新类。

以这种方式使用时,type 函数采用三个参数:

  • 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()

My name is Speaking Spot
My name is Speaking Whiskers

关于python - 除了父类(super class)之外,两个相同的 Python 类 - 如何避免重复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16027367/

相关文章:

python - pip 相当于 `npm install package --save-dev` 是什么?

C++类设计题

java - ArrayList 中的类型不匹配与多态性

Javascript原型(prototype)继承和对象创建

java - 为什么java不允许继承final类?

python - 将 Python 包上传到 PyPI

python - 如何在 Jupyter Notebook 中加载 CSV 文件?

Python类继承构造函数失败: What am I doing wrong?

ios - 从 Objective C 中的 Swift 类继承

python - pytest 中 actual 和 expected 的正确顺序是什么?