Python:在初始评估后给类添加父类

10 投票
2 回答
2472 浏览
提问于 2025-04-17 02:14

关于Python的一般问题

我正在导入一个Python库(我们叫它animals.py),它的类结构如下:

class Animal(object): pass

class Rat(Animal): pass

class Bat(Animal): pass

class Cat(Animal): pass

...

我想给每个物种类(比如RatBatCat等)添加一个父类(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 个回答

0

你真的应该尽量避免这样做。这听起来很奇怪,最后可能会让你很失望。

正如@agf提到的,你可以把Pet当作一个混合类来使用。如果你能告诉我们你为什么想要插入一个父类,我们可以帮你找到更好的解决办法。

3

你的方法基本上就是动态实现的方式。真正的问题是:这个新父类能带来什么好处?如果你想在已经存在的类的方法链中插入自己的方法,而那些方法本身写得不够好,你可能就插不进去;如果你是在添加新的方法(比如说一个接口层),那么你可能直接用函数就可以了。

我很喜欢Python的动态特性,使用你提供的代码我一点问题都没有。确保你有良好的单元测试(无论是动态的还是静态的;),并且修改继承结构确实能让你实现需要的功能,享受Python的乐趣吧!

撰写回答