Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用条件重写方法_Python_Oop - Fatal编程技术网

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^^