在 python 中初始化 class 中的 subclass
Initialize subclass within class in python
我正在使用字典初始化 class 以及 Python 中的两个子 class。是否可以在 init 中检查字典中的键并根据结果初始化两个 subclasses 中的一个?
例如:
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 方法。这会很好地工作,并且是 OObject Oriented Programming 的一个重要概念。如果要从超类调用 init
方法,请执行 super(self)
。如果您想调用任何其他方法,请执行 super.method()
并包含任何额外参数。
虽然这可能通过 python 的 类 的语义实现,但我认为这是一个糟糕的设计模式,应该避免。
在面向对象编程中,您的 类 应该代表数据和逻辑部分之间的划分。您现在正在做的是coupling Pet
超类及其子类 的logic/data。相反,您应该争取的是尽可能地 解耦 您的对象。这简化了 类 之间的接口,并帮助您编写尽可能通用的 类 并使用 sub类 来实现特定行为。
在您的情况下,您应该在特定宠物的 __init__
方法中对不同的宠物类型进行初始化。如果您以这种方式编写代码,从概念上讲,添加 new Pet
sub类 会容易得多 - 您需要做的就是从 Pet
继承并按应有的方式初始化子类。
您现在尝试实施的方法使实施 sub类 变得更加困难。实现者需要了解在子类中设置哪些变量以挂接到 Pet
类 初始化方案,然后需要进入 Pet
源代码并为初始化新的 Pet
子类类型。这很难做到,需要编辑多个 类 才能实现一个新的子类。
This question 也谈到了你试图实现的问题。
您发布的不是您的想法。在您的示例中,"Dog" 和 "Cat" 不是 "Pet" 的 sub类,它们是 inner 类。
我在下面发布了一些代码来演示您应该如何编写子 类。对于您所处情况下不同子 类 的实例化,最好使用 工厂模式 ,您可以 Google 并在下面作为示例包含在内。我还将工厂设置为能够 return 正确的字符串子类型,但这是一种丑陋的做事方式,所以我建议您不要使用该示例。
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.
我正在使用字典初始化 class 以及 Python 中的两个子 class。是否可以在 init 中检查字典中的键并根据结果初始化两个 subclasses 中的一个? 例如:
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 方法。这会很好地工作,并且是 OObject Oriented Programming 的一个重要概念。如果要从超类调用 init
方法,请执行 super(self)
。如果您想调用任何其他方法,请执行 super.method()
并包含任何额外参数。
虽然这可能通过 python 的 类 的语义实现,但我认为这是一个糟糕的设计模式,应该避免。
在面向对象编程中,您的 类 应该代表数据和逻辑部分之间的划分。您现在正在做的是coupling Pet
超类及其子类 的logic/data。相反,您应该争取的是尽可能地 解耦 您的对象。这简化了 类 之间的接口,并帮助您编写尽可能通用的 类 并使用 sub类 来实现特定行为。
在您的情况下,您应该在特定宠物的 __init__
方法中对不同的宠物类型进行初始化。如果您以这种方式编写代码,从概念上讲,添加 new Pet
sub类 会容易得多 - 您需要做的就是从 Pet
继承并按应有的方式初始化子类。
您现在尝试实施的方法使实施 sub类 变得更加困难。实现者需要了解在子类中设置哪些变量以挂接到 Pet
类 初始化方案,然后需要进入 Pet
源代码并为初始化新的 Pet
子类类型。这很难做到,需要编辑多个 类 才能实现一个新的子类。
This question 也谈到了你试图实现的问题。
您发布的不是您的想法。在您的示例中,"Dog" 和 "Cat" 不是 "Pet" 的 sub类,它们是 inner 类。 我在下面发布了一些代码来演示您应该如何编写子 类。对于您所处情况下不同子 类 的实例化,最好使用 工厂模式 ,您可以 Google 并在下面作为示例包含在内。我还将工厂设置为能够 return 正确的字符串子类型,但这是一种丑陋的做事方式,所以我建议您不要使用该示例。
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.