我有许多类被其他类包装以添加新功能。
不幸的是,包装类没有为它们包装的类实现传递函数,因此包装类不能与原始类互换使用。
我想动态创建包含包装器和原始类功能的类。
我的想法是创建一个混合类并使用一个工厂将其应用于现有类以动态创建一个新的双重用途类。这应该允许我编写一次混合,并且混合类用于通过一个对象从混合中提供原始功能或增强功能。
这就是我想要的东西:
class A:
def __init__(self):
self.name = 'A'
def doA(self):
print "A:", self.name
class B(A):
def __init__(self):
self.name = 'B'
def doB(self):
print "B:", self.name
class C(A):
def __init__(self):
self.name = 'C'
def doC(self):
print "C:", self.name
class D:
def doD(self):
print "D:", self.name
class BD(B,D):
pass
def MixinFactory(name, base_class, mixin):
print "Creating %s" % name
return class(base_class, mixin) # SyntaxError: invalid syntax
a, b, c, d, bd = A(), B(), C(), D(), BD()
bd2 = MixinFactory('BD2', B, D)()
cd = MixinFactory('CD', C, D)()
a.doA() # A: A
b.doA() # A: B
b.doB() # B: B
c.doA() # A: C
c.doC() # C: C
bd.doA() # A: B
bd.doB() # B: B
bd.doD() # D: B
bd2.doA() # A: B
bd2.doB() # B: B
bd2.doD() # D: B
cd.doA() # A: C
cd.doC() # C: C
cd.doD() # D: C
问题很明显,您不能只从函数返回一个类。虽然忽略了语法错误,但上面的代码确实显示了我想要实现的目标。
我玩过 type()
的三个参数变体,但无法让它工作,所以我不确定这是否是正确的方法。
我假设在 Python 中可以创建这种类型的混合工厂,那么我需要了解什么才能实现它?
作为Niklas R评论,this answer问题Python dynamic inheritance: How to choose base class upon instance creation?为我的查询提供了解决方案,但是 Ben此处的回答更好地解释了原因。
最佳答案
实际上你可以从一个函数中返回一个类。您的语法错误是您正在使用 keyword 类,就好像它是您可以调用的函数一样。
请记住,所有的类 block 都是创建一个新类,然后将您选择的名称绑定(bind)到它(在当前范围内)。所以只需在您的函数中放置一个类 block ,然后返回该类!
def mixinFactory(name, base, mixin):
class _tmp(base, mixin):
pass
_tmp.__name__ = name
return _tmp
如 ejucovy 所述, 你也可以直接调用type
:
def mixinFactory(name, base, mixin):
return type(name, (base, mixin), {})
这是可行的,因为它(通常)是类 block 的实际作用;它将您在类 block 中定义的所有名称收集到一个字典中,然后将类的名称、基类的元组和字典传递给 type
以构造新类。
但是,type
只不过是默认元类。类和其他任何东西一样都是对象,并且是类的实例。大多数类都是 type
的实例,但是如果涉及到另一个元类,您应该调用它而不是 type
,就像您不会调用 object
一样创建您的类的新实例。
您的 mixin(大概)没有定义元类,因此它应该与作为 type
子类的任何元类兼容。所以你可以使用 base
的任何类:
def mixinFactory(name, base, mixin):
return base.__class__(name, (base, mixin), {})
但是,S.Lott 的评论似乎确实是这个问题的最佳“答案”,除非您的 mixin 工厂正在做比创建新类更复杂的事情。这比提议的任何动态类创建变体都更清晰,输入更少:
class NewClass(base, mixin):
pass
关于python - 如何在 Python 中创建 Mixin 工厂?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9087072/