在python中初始化类内的子类

在python中初始化类内的子类,python,class,inheritance,subclass,Python,Class,Inheritance,Subclass,我正在使用字典初始化Python中的一个类和两个子类。是否可以在init中检查字典中的键,并根据结果初始化两个子类中的任何一个子类? 例如: Class Pet(): def __init__(self,dic): self.name=dic['name'] self.age=dic['age'] if dic['type']=='dog': #Initialize a dog which inherits all pet m

我正在使用字典初始化Python中的一个类和两个子类。是否可以在init中检查字典中的键,并根据结果初始化两个子类中的任何一个子类? 例如:

Class Pet():
    def __init__(self,dic):
       self.name=dic['name']
       self.age=dic['age']
       if dic['type']=='dog':
          #Initialize a dog which inherits all pet methods with name and age passed onto it 
       elif dic['type']=='cat':
          #Initialize a dog which inherits all pet methods with name and age passed onto it 


    def pet_methods():      
        # a bunch of pet methods that I would like to be inherited


    Class Dog():
       def __init__(self):
          self.dog_attributes=dic['dog_attributes']
    Class Cat():
       def __init__(self):
          self.cat_attributes=dic['cat_attributes']

if/else语句中可以使用什么代码?还是有更好的方法来组织代码?我很困惑,因为我似乎想在另一个init中调用init。

在子类中,您的
init
方法覆盖了原始超类的init方法。这将很好地工作,是面向对象编程的一个重要概念。如果要从超类调用
init
方法,请执行
super(self)
。如果要调用任何其他方法,请执行
super.method()
,并包含任何额外参数

在子类中,您的
init
方法覆盖了原始超类的init方法。这将很好地工作,是面向对象编程的一个重要概念。如果要从超类调用
init
方法,请执行
super(self)
。如果要调用任何其他方法,请执行
super.method()
,并包含任何额外参数

虽然python类的语义可以做到这一点,但我认为这是一种糟糕的设计模式,应该避免

在面向对象编程中,类应该表示数据和逻辑部分之间的划分。您现在正在做的是
Pet
超类及其子类的逻辑/数据。相反,您应该争取的是尽可能地解耦对象。这简化了类之间的接口,并帮助您编写尽可能通用的类,并使用子类实现特定的行为

在您的情况下,您应该在特定宠物的
\uuuu init\uuuu
方法中初始化不同的宠物类型。如果以这种方式编写代码,从概念上讲,添加新的
Pet
子类要容易得多-您需要做的就是从
Pet
继承并初始化子类

您现在尝试实现的方法使得实现子类变得更加困难。实现者需要了解在子类中设置哪些变量以连接到
Pet
类初始化方案,然后需要进入
Pet
源并实现初始化新
Pet
子类类型的新功能。这要困难得多,需要编辑多个类来实现一个新的子类


还讨论了您试图实现的问题。

虽然python类的语义可以实现这一点,但我认为这是一种糟糕的设计模式,应该避免

在面向对象编程中,类应该表示数据和逻辑部分之间的划分。您现在正在做的是
Pet
超类及其子类的逻辑/数据。相反,您应该争取的是尽可能地解耦对象。这简化了类之间的接口,并帮助您编写尽可能通用的类,并使用子类实现特定的行为

在您的情况下,您应该在特定宠物的
\uuuu init\uuuu
方法中初始化不同的宠物类型。如果以这种方式编写代码,从概念上讲,添加新的
Pet
子类要容易得多-您需要做的就是从
Pet
继承并初始化子类

您现在尝试实现的方法使得实现子类变得更加困难。实现者需要了解在子类中设置哪些变量以连接到
Pet
类初始化方案,然后需要进入
Pet
源并实现初始化新
Pet
子类类型的新功能。这要困难得多,需要编辑多个类来实现一个新的子类


还讨论了您试图实现的问题。

您发布的内容与您的想法不同。在您的示例中,“Dog”和“Cat”不是“Pet”的子类,它们是内部类。 我在下面发布了一些代码,演示如何编写子类。在您的情况下,为了实例化不同的子类,最好使用工厂模式,您可以在谷歌上搜索到它,我在下面给出了一个示例。我还将工厂设置为能够通过字符串返回正确的子类型,但这是一种丑陋的方法,因此我建议您不要使用该示例

class Pet:
    def __init__(self):
        pass

    def method1(self):
        print "Method 1 has been called."

    def method2(self):
        print "Method 2 has been called."

    def yelp(self):
        print "I am yelping"


class Dog(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am barking"


class Cat(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am meowing"


class PetFactory:
    def __init__(self):
        pass

    def acquire_dog(self):
        return Dog()

    def acquire_cat(self):
        return Cat()

    def acquire_pet_by_name(self, pet_type):
        if pet_type == "dog":
            return Dog()
        elif pet_type == "cat":
            return Cat()
这将产生:

>>> pet = Pet()
>>> dog = Dog()
>>> cat = Cat()
>>> dog.yelp()
I am barking
>>> cat.yelp()
I am meowing
>>> pet.yelp()
I am yelping
>>> pet_factory = PetFactory()
>>> pet_factory.acquire_cat().yelp()
I am meowing
>>> pet_factory.acquire_pet_by_name("cat").yelp()
I am meowing
>>> cat.method1()
Method 1 has been called.
>>> dog.method2()
Method 2 has been called.

你发布的不是你想的。在您的示例中,“Dog”和“Cat”不是“Pet”的子类,它们是内部类。 我在下面发布了一些代码,演示如何编写子类。在您的情况下,为了实例化不同的子类,最好使用工厂模式,您可以在谷歌上搜索到它,我在下面给出了一个示例。我还将工厂设置为能够通过字符串返回正确的子类型,但这是一种丑陋的方法,因此我建议您不要使用该示例

class Pet:
    def __init__(self):
        pass

    def method1(self):
        print "Method 1 has been called."

    def method2(self):
        print "Method 2 has been called."

    def yelp(self):
        print "I am yelping"


class Dog(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am barking"


class Cat(Pet):
    def __init__(self):
        Pet.__init__(self)

    def yelp(self):
        print "I am meowing"


class PetFactory:
    def __init__(self):
        pass

    def acquire_dog(self):
        return Dog()

    def acquire_cat(self):
        return Cat()

    def acquire_pet_by_name(self, pet_type):
        if pet_type == "dog":
            return Dog()
        elif pet_type == "cat":
            return Cat()
这将产生:

>>> pet = Pet()
>>> dog = Dog()
>>> cat = Cat()
>>> dog.yelp()
I am barking
>>> cat.yelp()
I am meowing
>>> pet.yelp()
I am yelping
>>> pet_factory = PetFactory()
>>> pet_factory.acquire_cat().yelp()
I am meowing
>>> pet_factory.acquire_pet_by_name("cat").yelp()
I am meowing
>>> cat.method1()
Method 1 has been called.
>>> dog.method2()
Method 2 has been called.

答案中的类如何是内部类而不是子类?它们继承自Pet,并在实现中使用动态调度(OOP的核心思想)。一个内部类是在另一个类中定义的类。我想你误解我了。我的类中没有一个是内部类,它们只是子类。在OP的代码提取中,它们都是内部类,但不是子类。您好,谢谢您的帮助。我确实是在用内胎