Python:在初始评估后给类添加父类
关于Python的一般问题
我正在导入一个Python库(我们叫它animals.py),它的类结构如下:
class Animal(object): pass
class Rat(Animal): pass
class Bat(Animal): pass
class Cat(Animal): pass
...
我想给每个物种类(比如Rat
、Bat
、Cat
等)添加一个父类(Pet
);但是,我不能更改我导入的库的实际源代码,所以必须在运行时进行更改。
下面的代码似乎可以实现这个目的:
import animals
class Pet(object): pass
for klass in (animals.Rat, animals.Bat, animals.Cat, ...):
klass.__bases__ = (Pet,) + klass.__bases__
这样做是将父类注入到Python中的继承树里,而不修改要更改的类的源定义的最佳方法吗?
动机背景
我想在一个控制实验室设备的大型库上添加持久性功能。对这个库进行修改是不可能的。我想试试ZODB的Persistent
。我不想写一个混合类/外观包装库,因为我的应用代码中有100多个类和很多需要更新的导入。我只是在我的入口点进行测试:设置数据库,像上面那样进行补丁(但通过对animals模块进行反射来获取物种类,而不是显式列出),然后在退出时关闭数据库。
我的请求
这是一个故意宽泛的问题。我对注入父类的不同方法感兴趣,并希望听听这些方法的优缺点。我同意这种运行时的操作会让代码变得非常混乱。如果我决定使用ZODB,我会做一些明确的事情。现在,作为一个普通的Python用户,我对一般情况感到好奇。
2 个回答
你真的应该尽量避免这样做。这听起来很奇怪,最后可能会让你很失望。
正如@agf提到的,你可以把Pet当作一个混合类来使用。如果你能告诉我们你为什么想要插入一个父类,我们可以帮你找到更好的解决办法。
你的方法基本上就是动态实现的方式。真正的问题是:这个新父类能带来什么好处?如果你想在已经存在的类的方法链中插入自己的方法,而那些方法本身写得不够好,你可能就插不进去;如果你是在添加新的方法(比如说一个接口层),那么你可能直接用函数就可以了。
我很喜欢Python的动态特性,使用你提供的代码我一点问题都没有。确保你有良好的单元测试(无论是动态的还是静态的;),并且修改继承结构确实能让你实现需要的功能,享受Python的乐趣吧!