简体   繁体   English

子类中的Python类继承自父类中的类

[英]Python class inside subclass inheriting from class inside parent class

The title is pretty much self explanatory, but I think this is better explained with an example. 标题几乎是不言自明的,但我认为可以通过示例更好地说明。

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

Hopefully the logic is correct. 希望逻辑是正确的。 I was trying to use super() with no success. 我试图使用super()失败。 Hopefully I can find a solution without using an explicit call to the parent class. 希望我可以找到一个解决方案,而无需使用对父类的显式调用。

Any thoughts? 有什么想法吗?

Thanks in advance! 提前致谢!

To inherit from the class you specified, according to the code you provided, all that is required is to define the class personality_2 like this: 要从您指定的类继承,请根据提供的代码,只需定义如下的personality_2类即可:

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

Now, as for your problem when trying to use super() , this might be because your base classes of Dog and Dog.personality_1 do not inherit from the python default class object which is required in order to use the super() method. 现在,关于您尝试使用super()时遇到的问题,这可能是因为DogDog.personality_1基类没有继承自使用default super()方法所需的python默认类object See this answer for details. 有关详细信息,请参见此答案。 If that is what you are after, all you need to do is modify your class declarations for Dog and Dog.personality_1 (or whatever they ultimately derive from) to the following: 如果您要这样做,那么您要做的就是将DogDog.personality_1类声明(或最终从它们派生的任何内容)修改为以下内容:

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

Then you can treat SocialDog.personality_2 just like any other subclass. 然后,您可以像对待其他任何子类一样对待SocialDog.personality_2 If you are using python 2, remember when using super() that you need to use the fully qualified name: 如果使用的是python 2,请记住在使用super()时需要使用完全限定名称:

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

Use the name of the outer class to reach the inner class: 使用外部类的名称访问内部类:

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

That said, this is a very weird thing you're doing, hiding the personality classes inside the dog classes, then using them outside ... 也就是说,这是一件很奇怪的事情,将个性类隐藏在狗类内部,然后在外部使用它们...

If a personality is that tightly coupled to a specific class like Dog or SocialDog , what makes personality_2 think it's safe to mess with the behaviour of personality_1 ? 如果一个人紧耦合到像一个特定的类DogSocialDog ,是什么让personality_2认为它是安全惹的行为personality_1 In fact, the personality methods should probably be Dog or SocialDog methods instead. 实际上,个性方法可能应该是DogSocialDog方法。

Or, if it doesn't really matter which dog gets which personality, why not leave the personality classes up at the module level, where they can be instantiated and inherited like any other class? 或者,如果哪只狗获得哪种个性并不重要,为什么不将个性类留在模块级别,可以像其他任何类一样实例化和继承它们呢? Your various Dog -derived classes would then take an optional personality argument when created: 创建后,各种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())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM