[英]How can I conditionally add in a mixin to the current class on instantiation?
我想要一個類,它根據傳遞給構造函數的參數添加混入。 這是我嘗試過的:
class MixinOne(object):
def print_name(self):
print("{} is using MixinOne.".format(self.name))
class MixinTwo(object):
def print_name(self):
print("{} is using MixinTwo.".format(self.name))
class Sub(object):
def __new__(cls, *args, **kwargs):
mixin = args[1]
if mixin == 'one':
bases = (MixinOne,) + cls.__bases__
elif mixin == 'two':
bases = (MixinTwo,) + cls.__bases__
return object.__new__(type('Sub', bases, dict(cls.__dict__)))
def __init__(self, name, mixin):
print('In Sub.__init__')
self.name = name
唯一的問題似乎是__init__
沒有被調用,所以print_name
方法將不起作用。
Sub
上的__init__
觸發?或者
這是使用元類的好地方。 您可以將自定義混合包含代碼放在元中,然后您的Sub
類不需要樣板:
class AutoMixinMeta(type):
def __call__(cls, *args, **kwargs):
try:
mixin = kwargs.pop('mixin')
name = "{}With{}".format(cls.__name__, mixin.__name__)
cls = type(name, (mixin, cls), dict(cls.__dict__))
except KeyError:
pass
return type.__call__(cls, *args, **kwargs)
class Sub(object):
__metaclass__ = AutoMixinMeta
def __init__(self, name):
self.name = name
現在您可以創建Sub
對象並按如下方式指定 mixin:
>>> s = Sub('foo', mixin=MixinOne)
>>> s.print_name()
foo is using MixinOne.
它會自動從 kwargs dict 中拉出,因此__init__
方法可以完全不知道它的存在。
注意:元類聲明語法在 Python 3 中發生了變化:
class Sub(metaclass = AutoMixinMeta):
def __init__(self, name):
self.name = name
__init__
僅在__new__
返回類的實例時調用。 您的動態類從 mixin 和Sub
的parents繼承,但不是從Sub
本身繼承。 如果您設置bases = (MixinOne, cls)
它可能會起作用。
編寫工廠函數(或類方法)而不是重載Sub
的構造。 更好的是,只需創建一些子類,而不是在運行時創建類。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.