Python:初次评估后,将父母添加到类
一般 Python 问题
我正在导入一个具有以下类结构的 Python 库(称为 Animals.py):
class Animal(object): pass
class Rat(Animal): pass
class Bat(Animal): pass
class Cat(Animal): pass
...
我想向每个物种类 (老鼠
、蝙蝠
、猫
、...);但是,我无法更改正在导入的库的实际源,因此它必须是运行时更改。
以下似乎可行:
import animals
class Pet(object): pass
for klass in (animals.Rat, animals.Bat, animals.Cat, ...):
klass.__bases__ = (Pet,) + klass.__bases__
这是在Python中将父类注入继承树而不修改要修改的类的源定义的最佳方法吗?
激励环境
我试图将持久性移植到控制实验室设备的大型库上。搞乱它是不可能的。我想尝试一下 ZODB 的 Persistent
。我不想编写 mixin/facade 包装器库,因为我正在处理 100 多个类以及应用程序代码中需要更新的大量导入。我仅通过侵入我的入口点来测试选项:设置数据库,如上所示进行修补(但在动物模块上进行内省,而不是显式列出物种类),然后在退出时关闭数据库。
Mea Culpa / 请求
这是一个特意提出的一般性问题。我对注射父母的不同方法感兴趣,并对这些方法的优缺点进行评论。我同意这种运行时的欺骗行为会使代码变得非常混乱。如果我选择 ZODB,我会做一些明确的事情。目前,作为 python 的普通用户,我对一般情况感到好奇。
General Python Question
I'm importing a Python library (call it animals.py) with the following class structure:
class Animal(object): pass
class Rat(Animal): pass
class Bat(Animal): pass
class Cat(Animal): pass
...
I want to add a parent class (Pet
) to each of the species classes (Rat
, Bat
, Cat
, ...); however, I cannot change the actual source of the library I'm importing, so it has to be a run time change.
The following seems to work:
import animals
class Pet(object): pass
for klass in (animals.Rat, animals.Bat, animals.Cat, ...):
klass.__bases__ = (Pet,) + klass.__bases__
Is this the best way to inject a parent class into an inheritance tree in Python without making modification to the source definition of the class to be modified?
Motivating Circumstances
I'm trying to graft persistence onto the a large library that controls lab equipment. Messing with it is out of the question. I want to give ZODB's Persistent
a try. I don't want to write the mixin/facade wrapper library because I'm dealing with 100+ classes and lots of imports in my application code that would need to be updated. I'm testing options by hacking on my entry point only: setting up the DB, patching as shown above (but pulling the species classes w/ introspection on the animals module instead of explicit listing) then closing out the DB as I exit.
Mea Culpa / Request
This is an intentionally general question. I'm interested in different approaches to injecting a parent and comments on the pros and cons of those approaches. I agree that this sort of runtime chicanery would make for really confusing code. If I settle on ZODB I'll do something explicit. For now, as a regular user of python, I'm curious about the general case.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的方法几乎就是如何动态地做到这一点。真正的问题是:这个新的父类添加了什么?如果您尝试将自己的方法插入到已存在的类中的方法链中,并且它们的编写不正确,那么您将无法这样做;如果您要添加原始方法(例如接口层),那么您可能只需使用函数即可。
我是一个拥护 Python 动态特性的人,并且使用您提供的代码不会有任何问题。确保您有良好的单元测试(动态或非动态;),并且修改继承树实际上可以让您做您需要的事情,并享受 Python!
Your method is pretty much how to do it dynamically. The real question is: What does this new parent class add? If you are trying to insert your own methods in a method chain that exists in the classes already there, and they were not written properly, you won't be able to; if you are adding original methods (e.g. an interface layer), then you could possibly just use functions instead.
I am one who embraces Python's dynamic nature, and would have no problem using the code you have presented. Make sure you have good unit tests in place (dynamic or not ;), and that modifying the inheritance tree actually lets you do what you need, and enjoy Python!
你应该非常努力地不要这样做。这很奇怪,而且很可能会以泪水结束。
正如 @agf 提到的,您可以使用 Pet 作为 mixin。如果您告诉我们更多有关为什么要插入父类的信息,我们可以帮助您找到更好的解决方案。
You should try really hard not to do this. It is strange, and will likely end in tears.
As @agf mentions, you can use Pet as a mixin. If you tell us more about why you want to insert a parent class, we can help you find a nicer solution.