代码之家  ›  专栏  ›  技术社区  ›  C.med

如何使用条件重写方法

  •  0
  • C.med  · 技术社区  · 7 年前

    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()
    

    希望我的例子是清楚的

    3 回复  |  直到 7 年前
        1
  •  2
  •   bruno desthuilliers    7 年前

    使用元类和继承的干净解决方案:

    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)()
    
        2
  •  1
  •   DeepSpace    7 年前

    虽然继承是这里的最佳解决方案,但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.__init__ Cat.__init__ 期望接受相同的参数。

        3
  •  0
  •   bruno desthuilliers    7 年前

    以下是如何实现您的目标:

    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")