python - 从类实例动态继承并将类型更改为新创建的类
问题描述
假设我有 2 个(或更多)动物类,猫和狗,它们都是需要sound
方法的 ABC 动物类的子类。
假设我想创建一个方法,将 Cat 或 Dog 的实例修改为 SuperCat 或 SuperDog 类的新实例,保留实例的初始化属性,但修改 sound 方法(使其调用大写)。Cat 和 Dog 具有不同的初始化和属性。
我目前通过在运行时动态创建类然后复制实例并更改其内部__class__
属性来实现这一点。
这感觉像是在作弊。处理此类问题的pythonic方式是什么?
库代码:
from abc import ABC, abstractmethod
from copy import deepcopy
class Animal(ABC):
@abstractmethod
def sound(self):
pass
class Cat(Animal):
def __init__(self,favorite_catnip="BrandName"):
self.favorite_catnip = favorite_catnip
def sound(self):
return "purr"
class Dog(Animal):
def __init__(self,best_friend="Human"):
self.best_friend = best_friend
def sound(self):
return "woof"
def createSuperAnimal(animal):
# Check that we at least got an animal
if not isinstance(animal,Animal):
raise TypeError("Given class instance needs to be an animal")
# Dynamically create new super animal class with loud sounds!
class SuperAnimal(type(animal)):
# Super animals have loud sounds
def sound(self):
return super().sound().upper()
# Make a copy of existing instance and change its class
# This gets us the initialized values for the Cat or Dog.
superAnimal = deepcopy(animal)
superAnimal.__class__ = SuperAnimal
return superAnimal
示例调用:
# initialize the two distinct sub-classes
dog = Dog()
cat = Cat()
print(dog.sound())
print(cat.sound())
# Create super animals
superDog = createSuperAnimal(dog)
superCat = createSuperAnimal(cat)
print(superDog.sound())
print(superCat.sound())
# Superdog has best friend, superCat has favorite_catnip
print(superDog.best_friend)
print(superCat.favorite_catnip)
输出:
woof
purr
WOOF
PURR
Human
BrandName
解决方案
推荐阅读
- ios - 无法更新 XCode:空间不足
- python - 如何在 RestrictedPython 中使用类
- excel - 组合多个 If 语句进行增长率计算
- java - 在 Spring 中将自动增量 @Id 限制为 6 位
- kubernetes - 使用 MetalLB 将公共 IP 添加到 Nginx 入口控制器
- tree - BFS 中的最大队列长度
- python - 如何解析交互式表格中的数据点?
- azure-cosmosdb - 我们可以在 Cosmos db 中一个容器的存储过程中调用不同的容器吗?
- python - 使用列表理解,如何在遇到某个 input/stop_word 之前获取用户输入?
- terraform - Terraform for 循环获取索引