【问题标题】:Python class inside subclass inheriting from class inside parent class子类中的Python类继承自父类中的类
【发布时间】:2014-11-20 04:10:53
【问题描述】:

标题几乎是不言自明的,但我认为这最好用一个例子来解释。

class Dog():

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

    def get_name(self):
        return self.name

    def get_color(self):
        return body_color()

    class personality_1():

        def get_happiness(self):
            return happiness_with_owner()

        def get_sadness(self):
            return sadness()
        ## A lot more personality methods here


class SocialDog(Dog):

    # Override regular method
    def get_color(self):
        return face_color()

    # I want to override the personality 1 class but not completely, just one method
    class personality_2(>>>How to inherit from personality_1?<<<):
        # Now, I would like to override just one method of personality 1:
        def get_happiness(self):
        return happiness_with_others()

希望逻辑是正确的。我试图使用 super() 没有成功。希望我可以在不显式调用父类的情况下找到解决方案。

有什么想法吗?

提前致谢!

【问题讨论】:

    标签: python class inheritance subclass


    【解决方案1】:

    要从您指定的类继承,根据您提供的代码,只需像这样定义类personality_2

    class SocialDog(Dog):
      #...
        class personality_2(Dog.personality_1):
          #...
    

    现在,至于您在尝试使用super() 时遇到的问题,这可能是因为您的DogDog.personality_1 的基类没有继承自python 默认类object,这是使用所需的super() 方法。有关详细信息,请参阅this 答案。如果这就是您所追求的,您需要做的就是将 DogDog.personality_1(或它们最终派生的任何东西)的类声明修改为以下内容:

    class Dog(object):
      #...
      class personality_1(object):
        #...
    

    然后你可以像对待任何其他子类一样对待SocialDog.personality_2。如果您使用的是 python 2,请记住在使用 super() 时需要使用完全限定名称:

    super(SocialDog.personality_2, self).super_class_method()
    super(SocialDog.personality_2, self).super_class_field
    

    【讨论】:

    • 看起来当你发布这个时我还在输入我的。顺便说一句,Python 2 继承自对象很好……我已经习惯了 Python 3。
    • 感谢@Sam,我认为这直接回答了原始问题。然而,Kevin J. Chase 证实了我最初的怀疑,即逻辑可以重新安排。你也同意吗?问题是我有多种动物(神、牛等),每种动物的个性都非常不同,所以我嵌套这些类的原因是为了它们不会污染外层空间,每种动物都有 2 个类。
    • @chrisfromlocalgroup:这取决于个体对动物的依赖程度,以及有多少。您可能只需要少数几个人就可以处理数十种动物。 (AngryPersonalityDog 中的 CowSnake 中的 Snake 有很大不同吗?)也就是说,可能工作的最简单的事情是使 AngryDog Dog 的子类,带有更强调的 get_madder 方法。创建和使用其中的一些类,如果您重复大量应该放入单独的 Personality 类的方法,应该很快就会清楚。
    【解决方案2】:

    使用外部类的名称到达内部类:

    class SocialDog(Dog):
        class personality_2(Dog.personality_1):
            # ...
    

    也就是说,这是你在做的一件很奇怪的事情,将个性类隐藏在狗类中,然后在外部使用它们...

    如果一个个性DogSocialDog 等特定类紧密耦合,那么是什么让personality_2 认为与personality_1 的行为混淆是安全的?其实个性方法应该是Dog或者SocialDog方法吧。

    或者,如果哪只狗获得哪种性格并不重要,为什么不将性格类留在模块级别,在那里它们可以像任何其他类一样被实例化和继承?然后,您的各种Dog 派生类将在创建时采用可选的personality 参数:

    class WolfPersonality(DogPersonality):
        # ...
    
    class Wolf(Dog):
        def __init__(self, personality=None):
            if personality is None:
                personality = WolfPersonality()
            self.personality = personality
            # ...
    
    # Later...
    wolf = Wolf()
    wolf_puppy = Wolf(FriendlyDogPersonality())
    

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多