使用一组方法和属性(包装器)扩展独立 类
Extend independent classes with a set of methods and attributes (wrapper)
我的目标是创建一个 class 来扩展具有一组功能的不同 classes。
在下面的代码中,我能够创建问题的解决方案,但对我来说,这似乎不是解决问题的方法。
要求:
- 基础 classes (Cat, Dog) 不能改变。
- 具有附加功能(Pet_Dog、Pet_Cat)的 classes 应该具有最少的代码量,因为我需要很多代码,只需稍作改动。
- 我需要能够导入 BaseClasses (Cat, Dog) 以及增强的 class (Pet_Dog, Pet_Cat).
我的 "solution" 到目前为止:
class Cat:
def __init__(self, legs):
self.legs = 4
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = 4
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
def create_pet(BaseClass):
class Pet(BaseClass):
has_owner = True
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
def plays_with_owner(self):
print('playing with owner...')
return Pet
class Pet_Dog(Dog):
def __init__(self, BaseClass, name, legs):
self.__class__ = create_pet(BaseClass)(name, legs).__class__
self.__init__(name, legs)
class Pet_Cat(Cat):
def __init__(self, BaseClass, name, legs):
self.__class__ = create_pet(BaseClass)(name, legs).__class__
self.__init__(name, legs)
print('Create Pet Dog')
pet_dog = Pet_Dog(Dog, 'Woofer', 4)
print('Dog Name:', pet_dog.name)
print('Dog Lives:', pet_dog.hobby)
print('Dog Owner:', pet_dog.has_owner)
pet_dog.make_sound()
pet_dog.chase_tail()
pet_dog.plays_with_owner()
在 Python 中,您可以拥有继承自多个其他 class 的 class,因此我们可以制作 Cat
和 Dog
class,以及单独的Pet
class。然后我们可以让 Pet_Cat
和 Pet_Dog
继承自 Pet
和它们各自的动物,即:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
class Pet:
has_owner = True
name = None
def plays_with_owner(self):
print('playing with owner...')
class Pet_Dog(Dog, Pet):
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
class Pet_Cat(Cat, Pet):
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
print('Create Pet Dog')
pet_dog = Pet_Dog('Woofer', 4)
print('Dog Name:', pet_dog.name)
print('Dog Lives:', pet_dog.hobby)
print('Dog Owner:', pet_dog.has_owner)
pet_dog.make_sound()
pet_dog.chase_tail()
pet_dog.plays_with_owner()
输出:
Create Pet Dog
Dog Name: Woofer
Dog Lives: Digging holes
Dog Owner: True
Woof!
Chasing tail
playing with owner...
编辑:
如果你想在两者上都使用 init 函数,请改用它:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
class Pet:
def __init__(self):
self.has_owner = True
self.name = None
def plays_with_owner(self):
print('playing with owner...')
class Pet_Dog(Dog, Pet):
def __init__(self, name, legs):
Dog.__init__(self, legs)
Pet.__init__(self)
self.name = name
class Pet_Cat(Cat, Pet):
def __init__(self, name, legs):
Cat.__init__(self, legs)
Pet.__init__(self)
self.name = name
如果你真的想在这里使用继承,可以使用多重继承和协同super
调用来避免无用的重复:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
class Pet:
def __init__(self, name, *args, **kwargs):
self.has_owner = True
self.name = name
super().__init__(*args, **kwargs)
def plays_with_owner(self):
print('playing with owner...')
# Pet has to come before the "animal" class for the cooperative
# super() call to work
class PetCat(Pet, Cat):
pass
class PetDog(Pet, Dog):
pass
您甚至可以自动创建这些子类,但这不一定是一种改进:
def make_pet_class(name, base):
return type.__new__(name, (Pet, base), {})
PetCat = make_pet_class("PetCat", Cat)
现在继承不一定是解决所有问题的最佳方案。继承主要是一种非常受限的组合/委托形式,Python 使组合/委托非常容易:
class Pet:
def __init__(self, name, animal):
self._animal = animal
self.name = name
self.has_owner = True
def plays_with_owner(self):
print('playing with owner...')
def __getattr__(self, attr):
return getattr(self._animal, attr)
kitty = Pet("kitty", Cat(4))
pluto = Pet("pluto", Dog(4))
我的目标是创建一个 class 来扩展具有一组功能的不同 classes。 在下面的代码中,我能够创建问题的解决方案,但对我来说,这似乎不是解决问题的方法。
要求:
- 基础 classes (Cat, Dog) 不能改变。
- 具有附加功能(Pet_Dog、Pet_Cat)的 classes 应该具有最少的代码量,因为我需要很多代码,只需稍作改动。
- 我需要能够导入 BaseClasses (Cat, Dog) 以及增强的 class (Pet_Dog, Pet_Cat).
我的 "solution" 到目前为止:
class Cat:
def __init__(self, legs):
self.legs = 4
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = 4
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
def create_pet(BaseClass):
class Pet(BaseClass):
has_owner = True
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
def plays_with_owner(self):
print('playing with owner...')
return Pet
class Pet_Dog(Dog):
def __init__(self, BaseClass, name, legs):
self.__class__ = create_pet(BaseClass)(name, legs).__class__
self.__init__(name, legs)
class Pet_Cat(Cat):
def __init__(self, BaseClass, name, legs):
self.__class__ = create_pet(BaseClass)(name, legs).__class__
self.__init__(name, legs)
print('Create Pet Dog')
pet_dog = Pet_Dog(Dog, 'Woofer', 4)
print('Dog Name:', pet_dog.name)
print('Dog Lives:', pet_dog.hobby)
print('Dog Owner:', pet_dog.has_owner)
pet_dog.make_sound()
pet_dog.chase_tail()
pet_dog.plays_with_owner()
在 Python 中,您可以拥有继承自多个其他 class 的 class,因此我们可以制作 Cat
和 Dog
class,以及单独的Pet
class。然后我们可以让 Pet_Cat
和 Pet_Dog
继承自 Pet
和它们各自的动物,即:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
class Pet:
has_owner = True
name = None
def plays_with_owner(self):
print('playing with owner...')
class Pet_Dog(Dog, Pet):
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
class Pet_Cat(Cat, Pet):
def __init__(self, name, legs):
super().__init__(legs)
self.name = name
print('Create Pet Dog')
pet_dog = Pet_Dog('Woofer', 4)
print('Dog Name:', pet_dog.name)
print('Dog Lives:', pet_dog.hobby)
print('Dog Owner:', pet_dog.has_owner)
pet_dog.make_sound()
pet_dog.chase_tail()
pet_dog.plays_with_owner()
输出:
Create Pet Dog
Dog Name: Woofer
Dog Lives: Digging holes
Dog Owner: True
Woof!
Chasing tail
playing with owner...
编辑:
如果你想在两者上都使用 init 函数,请改用它:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
def make_sound(self):
print('Meow!')
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
def make_sound(self):
print('Woof!')
def chase_tail(self):
print('Chasing tail')
class Pet:
def __init__(self):
self.has_owner = True
self.name = None
def plays_with_owner(self):
print('playing with owner...')
class Pet_Dog(Dog, Pet):
def __init__(self, name, legs):
Dog.__init__(self, legs)
Pet.__init__(self)
self.name = name
class Pet_Cat(Cat, Pet):
def __init__(self, name, legs):
Cat.__init__(self, legs)
Pet.__init__(self)
self.name = name
如果你真的想在这里使用继承,可以使用多重继承和协同super
调用来避免无用的重复:
class Cat:
def __init__(self, legs):
self.legs = legs
self.lives = 9
class Dog:
def __init__(self, legs):
self.legs = legs
self.hobby = 'Digging holes'
class Pet:
def __init__(self, name, *args, **kwargs):
self.has_owner = True
self.name = name
super().__init__(*args, **kwargs)
def plays_with_owner(self):
print('playing with owner...')
# Pet has to come before the "animal" class for the cooperative
# super() call to work
class PetCat(Pet, Cat):
pass
class PetDog(Pet, Dog):
pass
您甚至可以自动创建这些子类,但这不一定是一种改进:
def make_pet_class(name, base):
return type.__new__(name, (Pet, base), {})
PetCat = make_pet_class("PetCat", Cat)
现在继承不一定是解决所有问题的最佳方案。继承主要是一种非常受限的组合/委托形式,Python 使组合/委托非常容易:
class Pet:
def __init__(self, name, animal):
self._animal = animal
self.name = name
self.has_owner = True
def plays_with_owner(self):
print('playing with owner...')
def __getattr__(self, attr):
return getattr(self._animal, attr)
kitty = Pet("kitty", Cat(4))
pluto = Pet("pluto", Dog(4))