Python 如何使用条件重写方法
我会给你看我的剧本,然后我解释我想做什么Python 如何使用条件重写方法,python,oop,Python,Oop,我会给你看我的剧本,然后我解释我想做什么 class Animal(object): def __init__(self,name=None): self.name=name if name=="dog": object=Dog() if name=="cat": object=Cat() def execute(self): print("I am animal")
class Animal(object):
def __init__(self,name=None):
self.name=name
if name=="dog":
object=Dog()
if name=="cat":
object=Cat()
def execute(self):
print("I am animal")
class Dog:
def __init__(self):
pass
def execute(self):
print("I am a dog")
class Cat:
def __init__(self):
pass
def execute(self):
print("I am a cat")
if __name__ =="__main__":
instanceAnimal=Animal("cat") # I would like to get "I am a cat" but I got "I am animal"
instanceAnimal.execute()
我知道这不是一个好方法,但是我有一个用例,我想实例化一个实例动物,通过在输入中给定一个名称,这个类将调用适当的执行
希望我的例子很清楚虽然继承是这里的最佳解决方案,但OP特别要求另一种解决方案
object=Dog()
或object=Cat()
没有任何用处。它将一个Dog
或Cat
实例分配给局部变量object
,就是这样。它与任何东西都没有关系
您必须在Animal
中保留对它的引用,并将Animal.execute
绑定到相应的execute
方法
此外,还可以使用字典使初始化更加简洁:
class Dog:
def execute(self):
print("I am a dog")
class Cat:
def execute(self):
print("I am a cat")
class Animal(object):
names_to_classes = {'dog': Dog, 'cat': Cat}
def __init__(self, name=None):
self.name = name
try:
self.object = self.names_to_classes[name]()
except KeyError:
raise TypeError('name must be either "dog" or "cat"')
def execute(self):
self.object.execute()
instanceAnimal = Animal("cat")
instanceAnimal.execute()
instanceAnimal = Animal("dog")
instanceAnimal.execute()
instanceAnimal = Animal("penguin")
instanceAnimal.execute()
输出
I am a cat
I am a dog
TypeError: name must be either "dog" or "cat"
这种方法的缺点是,
Dog.\uuu init\uu
和Cat.\uuu init\uu
希望接受相同的参数 虽然继承是这里的最佳解决方案,但OP特别要求另一种解决方案
object=Dog()
或object=Cat()
没有任何用处。它将一个Dog
或Cat
实例分配给局部变量object
,就是这样。它与任何东西都没有关系
您必须在Animal
中保留对它的引用,并将Animal.execute
绑定到相应的execute
方法
此外,还可以使用字典使初始化更加简洁:
class Dog:
def execute(self):
print("I am a dog")
class Cat:
def execute(self):
print("I am a cat")
class Animal(object):
names_to_classes = {'dog': Dog, 'cat': Cat}
def __init__(self, name=None):
self.name = name
try:
self.object = self.names_to_classes[name]()
except KeyError:
raise TypeError('name must be either "dog" or "cat"')
def execute(self):
self.object.execute()
instanceAnimal = Animal("cat")
instanceAnimal.execute()
instanceAnimal = Animal("dog")
instanceAnimal.execute()
instanceAnimal = Animal("penguin")
instanceAnimal.execute()
输出
I am a cat
I am a dog
TypeError: name must be either "dog" or "cat"
这种方法的缺点是,
Dog.\uuu init\uu
和Cat.\uuu init\uu
希望接受相同的参数 以下是如何实现您的目标:
class Animal(object):
def __init__(self, name=None):
if name == 'cat':
self._object = Cat()
elif name == 'dog':
self._object = Dog()
else:
self._object = None
def execute(self):
if self._object is not None:
self._object.execute()
else:
print("I am animal")
以下是如何实现您的目标:
class Animal(object):
def __init__(self, name=None):
if name == 'cat':
self._object = Cat()
elif name == 'dog':
self._object = Dog()
else:
self._object = None
def execute(self):
if self._object is not None:
self._object.execute()
else:
print("I am animal")
使用元类和继承的干净解决方案:
class AnimalType(type):
_classes = {}
def __init__(cls, name, attribs, bases):
super(AnimalType, cls).__init__(name, attribs, bases)
cls._classes[name.lower()] = cls
class Animal(object):
__metaclass__ = AnimalType
def __new__(cls, name=None):
newcls = type(cls)._classes.get(name, Animal)
return object.__new__(newcls, name)
def __init__(self, name=None):
self.name = name
def execute(self):
print("I am animal")
class Dog(Animal):
def execute(self):
print("I am a dog")
class Cat(Animal):
def execute(self):
print("I am a cat")
如果您根本不想继承,只需使用工厂函数:
class Animal(object):
def execute(self):
print("I am animal")
class Dog:
def execute(self):
print("I am a dog")
class Cat:
def execute(self):
print("I am a cat")
_clsmap = {
"animal": Animal,
"dog": Dog,
"cat": Cat
}
def make_animal(name):
return _clsmap.get(name, Animal)()
使用元类和继承的干净解决方案:
class AnimalType(type):
_classes = {}
def __init__(cls, name, attribs, bases):
super(AnimalType, cls).__init__(name, attribs, bases)
cls._classes[name.lower()] = cls
class Animal(object):
__metaclass__ = AnimalType
def __new__(cls, name=None):
newcls = type(cls)._classes.get(name, Animal)
return object.__new__(newcls, name)
def __init__(self, name=None):
self.name = name
def execute(self):
print("I am animal")
class Dog(Animal):
def execute(self):
print("I am a dog")
class Cat(Animal):
def execute(self):
print("I am a cat")
如果您根本不想继承,只需使用工厂函数:
class Animal(object):
def execute(self):
print("I am animal")
class Dog:
def execute(self):
print("I am a dog")
class Cat:
def execute(self):
print("I am a cat")
_clsmap = {
"animal": Animal,
"dog": Dog,
"cat": Cat
}
def make_animal(name):
return _clsmap.get(name, Animal)()
为什么不制作一个返回适当对象的(工厂)函数呢?您正在从
Animal
类调用execute
函数,因此除了“我是动物”之外,您不能返回任何东西。您的Cat
对象实际上也没有连接到Animal
类,可能self.species=Cat()
我想说print
函数也应该是\u str\u
。我同意工厂函数可能是一种更好的方法,假设您出于某些实质性原因不能使用继承谢谢,我也会尝试使用工厂函数,但是@DeepSpace solution对我有用为什么不创建(工厂)返回相应对象的函数?您正在从Animal
类调用execute
函数,因此只能返回“I am Animal”。您的Cat
对象实际上也没有连接到Animal
类,可能self.species=Cat()
我想说print
函数也应该是\u str\u
。我同意工厂函数可能是一种更好的方法,假设您出于某些实质性原因不能使用继承谢谢,我也会尝试使用工厂函数,但@DeepSpace solution worked for meThank you@bruno desthuillers^^谢谢@bruno desthuillers^^