Python 中的动态继承
- 2025-03-21 09:07:00
- admin 原创
- 56
问题描述:
假设我有一个类的 2 个不同实现
class ParentA:
def initialize(self):
pass
def some_event(self):
pass
def order(self, value):
# handle order in some way for Parent A
class ParentB:
def initialize(self):
pass
def some_event(self):
pass
def order(self, value):
# handle order in another for Parent B
我怎样才能动态地让某些第三类从其中任何一个继承ParentA
或者ParentB
基于类似的东西?
class MyCode:
def initialize(self):
self.initial_value = 1
def some_event(self):
# handle event
order(self.initial_value)
# let MyCode inherit from ParentA and run
run(my_code, ParentA)
解决方案 1:
只需将类对象存储在一个变量中(在下面的示例中,它被命名为base
),然后在语句的基类规范中使用该变量class
。
def get_my_code(base):
class MyCode(base):
def initialize(self):
...
return MyCode
my_code = get_my_code(ParentA)
解决方案 2:
另外,您可以使用type
内置函数。作为可调用函数,它接受参数:(name, bases, dct
最简单的形式)。
def initialize(self):
self.initial_value = 1
def some_event(self):
# handle event
order(self.initial_value)
subclass_body_dict = {
"initialize": initialize,
"some_event": some_event
}
base_class = ParentA # or ParentB, as you wish
MyCode = type("MyCode", (base_class, ), subclass_body_dict)
这比 snx2 解决方案更明确,但我仍然更喜欢他的方式。
PS.当然,您不必存储base_class或subclass_body_dict,您可以在type()
调用中构建这些值,如下所示:
MyCode = type("MyCode", (ParentA, ), {
"initialize": initialize,
"some_event": some_event
})
解决方案 3:
作为Chris 的答案实现shx2 的答案的记忆建议的替代方案,我更喜欢使用记忆装饰器(最终结果仍然是一个类,但对我来说更清楚的是该函数是接口),并且还用于setdefault
简化添加到备忘录字典的操作,并且不将名称转换为字符串,而是使用元组bases
本身作为键,从而将代码简化为:
class Memoize:
def __init__(self, f):
self.f = f
self.memo = {}
def __call__(self, *args):
return self.memo.setdefault(args, self.f(*args))
class ParentA:
def initialize(self):
pass
class ParentB:
def initialize(self):
pass
@Memoize
def get_my_code(base):
class MyCode(base):
def initialize(self):
pass
return MyCode
a1 = get_my_code(ParentA)
a2 = get_my_code(ParentA)
b1 = get_my_code(ParentB)
print(a1 is a2) # True
print(a1 is b1) # False
(这不是一个好的例子,因为提供的代码除了覆盖父类的方法之外实际上没有做任何事情initialize
......)
解决方案 4:
就像一个快速复制粘贴的代码片段一样,我添加了shx2 的答案中的注释来创建它(使用created_classes
dict 属性进行记忆,以便使用同一个类的连续相同调用创建的类将产生相同的类):
class ParentA:
val = "ParentA"
class ParentB:
val = "ParentB"
class DynamicClassCreator():
def __init__(self):
self.created_classes = {}
def __call__(self, *bases):
rep = ",".join([i.__name__ for i in bases])
if rep in self.created_classes:
return self.created_classes[rep]
class MyCode(*bases):
pass
self.created_classes[rep] = MyCode
return MyCode
creator = DynamicClassCreator()
instance1 = creator(ParentA, ParentB)()
print(instance1.val) #prints "ParentA"
instance2 = creator(ParentB, ParentA)()
print(instance2.val) #prints "ParentB"
如果你想变得更有想象力,你甚至可以将 DynamicClassCreator 变成一个单例:https://stackoverflow.com/a/7346105/5122790
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD