我有一個類Parent
。我想爲Parent
定義一個__new__
,所以它在實例化時會有一些魔力(爲什麼,請參閱腳註)。我也希望子類從這個類和其他類繼承來獲得父類的特性。 Parent
的__new__
將返回子類的基類和Parent
類的子類的實例。Python多重繼承:哪個__new__調用?
這是怎樣的子類將被定義:
class Child(Parent, list):
pass
但現在我不知道該怎麼__new__
在Parent
的__new__
調用。如果我打電話object.__new__
,上面的Child
示例抱怨應該調用list.__new__
。但Parent
怎麼知道?我做了工作,所以它遍歷所有__bases__
,並調用每個__new__
一個try:
塊中:
class Parent(object):
def __new__(cls, *args, **kwargs):
# There is a special wrapper function for instantiating instances of children
# classes that passes in a 'bases' argument, which is the __bases__ of the
# Children class.
bases = kwargs.get('bases')
if bases:
cls = type('name', bases + (cls,), kwargs.get('attr', {}))
for base in cls.__mro__:
if base not in (cls, MyMainType):
try:
obj = base.__new__(cls)
break
except TypeError:
pass
return obj
return object.__new__(cls)
但這只是看起來像一個黑客。當然,這樣做肯定有更好的方法嗎?
謝謝。
- 我想用
__new__
是這樣我就可以返回具有分配給類的一些動態屬性(屬性__int__
魔術等)的子類的對象的理由。 I could have done this in__init__
,但如果新類具有不同的內部結構,則無法修改self.__class__
(__init__
),這是由於多重繼承造成的。
我有一個答案,但後來我意識到我完全誤解了你的問題,所以我刪除了它,然後修改它並取消刪除它。我認爲新的答案解決了你的問題,並將工作。我做了一些最小的測試。 – Omnifarious 2010-01-26 03:03:42
你明顯地進入了元類編程領域,既棘手又奇妙。你使用__new__得到錯誤的原因是''object'和內建類型像'list'和'dict',以及'__slots__'對象都有不同的內存佈局。 更深入地瞭解你正在努力完成什麼將會有很大的幫助。您可能還想看看__metaclass__插槽中使用類裝飾器或函數。 – 2010-01-26 03:27:32
我不知道你爲什麼需要修改自己的.__ class__,你沒有提到。如果你需要在__new__中這樣做複雜的魔術,一個解決方案往往更容易,根本不用它,而是使用工廠。 – 2010-01-26 05:59:18