Here's the coding problem I am trying to solve... I have a base class, let's say Animal, and it has two subclasses, say Dog and Cat. My class Animal has a method, make_baby(), that both Dog and Cat will inherit. The trick I'm having trouble pulling off is that I want the return value to be a new instance of the subclass that called the function but with different attribute values, i.e. Dog.make_baby() should return a new Dog and Cat.make_baby() will return a new Cat.
这是我试图解决的编码问题...我有一个基类,让我们说动物,它有两个子类,比如Dog和Cat。我的类Animal有一个方法,make_baby(),Dog和Cat都会继承。我无法解决的诀窍是我希望返回值是调用函数但具有不同属性值的子类的新实例,即Dog.make_baby()应该返回一个新的Dog和Cat.make_baby( )将返回一只新猫。
I previously tried returning "type(self)()", but this is no good because type() return a type object, not a class.
我之前尝试返回“type(self)()”,但这并不好,因为type()返回一个类型对象,而不是类。
Here is the full example code:
这是完整的示例代码:
Class Animal():
def __init__(self, color):
self.color = color
def make_baby():
new_color = rand_color # a randomly chosen color
return #??? new class of the same type that called the method
Class Dog(Animal):
def pet():
print '*pant*'
Class Cat(Animal):
def pet():
print 'purrr'
So I'd like to avoid writing a make_baby() method for Dogs and Cats because the idea is that the method is exactly the same except for the returned class. I'd also like to avoid a bunch of if statements because I'd like to make and arbitrarily large number of subclasses to Animal.
因此,我想避免为Dogs和Cats编写一个make_baby()方法,因为除了返回的类之外,该方法完全相同。我还想避免一堆if语句,因为我想为Animal制作任意大量的子类。
3 个解决方案
#1
10
You wrote:
你写了:
this is no good because type() return a type object, not a class.
这不好,因为type()返回一个类型对象,而不是一个类。
A type is a class, if you're using new-style classes. If you're using Python 3, you're set; all Python 3 classes are "new-style." If you're using Python 2.x, derive your class from object
(or from something else that derives from object, like any built-in Python type).
如果您使用的是新式类,则类型是一个类。如果您正在使用Python 3,那么您已经设置好了;所有Python 3类都是“新风格”。如果您正在使用Python 2.x,则从对象(或从派生自对象的其他内容,如任何内置Python类型)派生您的类。
But what you really want here is a class method, where you get a reference to the class passed in automatically.
但是你真正想要的是一个类方法,在这里你可以获得对自动传入的类的引用。
class Animal(object):
def __init__(self, color):
self.color = color
@classmethod
def make_baby(cls):
return cls(rand_color) # randomly-chosen color
You can call it on the class (e.g. Animal.make_baby()
or Dog.make_baby()
) or on an instance; either way the method still receives the class as the first argument.
您可以在课程上调用它(例如Animal.make_baby()或Dog.make_baby())或实例;无论哪种方式,该方法仍然接收类作为第一个参数。
#2
3
type() can be used to construct entirely new classes. What you want is:
type()可用于构造全新的类。你想要的是:
class Animal():
def __init__(self, color):
self.color = color
def make_baby(self):
new_color = rand_color # a randomly chosen color
return self.__class__(new_color)
#3
3
You approach will totally work! Just use new style classes.
你的方法将完全奏效!只需使用新的样式类。
Class Animal(object):
def __init__(self, color):
self.color = color
def make_baby(self):
new_color = rand_color # a randomly chosen color
return type(self)(new_color)
Class Dog(Animal):
def pet():
print '*pant*'
Class Cat(Animal):
def pet():
print 'purrr'
However, if make_baby(self)
is not relying on details of self
, what you want is a class-wide factory method, like in @Kindall's answer.
但是,如果make_baby(self)不依赖于self的细节,那么你想要的是一个类范围的工厂方法,就像@ Kindall的答案一样。
#1
10
You wrote:
你写了:
this is no good because type() return a type object, not a class.
这不好,因为type()返回一个类型对象,而不是一个类。
A type is a class, if you're using new-style classes. If you're using Python 3, you're set; all Python 3 classes are "new-style." If you're using Python 2.x, derive your class from object
(or from something else that derives from object, like any built-in Python type).
如果您使用的是新式类,则类型是一个类。如果您正在使用Python 3,那么您已经设置好了;所有Python 3类都是“新风格”。如果您正在使用Python 2.x,则从对象(或从派生自对象的其他内容,如任何内置Python类型)派生您的类。
But what you really want here is a class method, where you get a reference to the class passed in automatically.
但是你真正想要的是一个类方法,在这里你可以获得对自动传入的类的引用。
class Animal(object):
def __init__(self, color):
self.color = color
@classmethod
def make_baby(cls):
return cls(rand_color) # randomly-chosen color
You can call it on the class (e.g. Animal.make_baby()
or Dog.make_baby()
) or on an instance; either way the method still receives the class as the first argument.
您可以在课程上调用它(例如Animal.make_baby()或Dog.make_baby())或实例;无论哪种方式,该方法仍然接收类作为第一个参数。
#2
3
type() can be used to construct entirely new classes. What you want is:
type()可用于构造全新的类。你想要的是:
class Animal():
def __init__(self, color):
self.color = color
def make_baby(self):
new_color = rand_color # a randomly chosen color
return self.__class__(new_color)
#3
3
You approach will totally work! Just use new style classes.
你的方法将完全奏效!只需使用新的样式类。
Class Animal(object):
def __init__(self, color):
self.color = color
def make_baby(self):
new_color = rand_color # a randomly chosen color
return type(self)(new_color)
Class Dog(Animal):
def pet():
print '*pant*'
Class Cat(Animal):
def pet():
print 'purrr'
However, if make_baby(self)
is not relying on details of self
, what you want is a class-wide factory method, like in @Kindall's answer.
但是,如果make_baby(self)不依赖于self的细节,那么你想要的是一个类范围的工厂方法,就像@ Kindall的答案一样。