我有從基類派生的類,和具有的代碼如何改變基類
例如許多許多線
class AutoComplete(TextCtrl):
.....
我想要做的是改變的基類,使得它像
class AutoComplete(PriceCtrl):
.....
我有兩種類型的自動完成的使用,可能是想增加更多的基類,所以怎麼能我動態地做到這一點?
組成將是一個解決方案,但我不想修改很多代碼。
任何簡單的解決方案?
我有從基類派生的類,和具有的代碼如何改變基類
例如許多許多線
class AutoComplete(TextCtrl):
.....
我想要做的是改變的基類,使得它像
class AutoComplete(PriceCtrl):
.....
我有兩種類型的自動完成的使用,可能是想增加更多的基類,所以怎麼能我動態地做到這一點?
組成將是一個解決方案,但我不想修改很多代碼。
任何簡單的解決方案?
你可以有一個工廠爲你的類:
def completefactory(baseclass):
class AutoComplete(baseclass):
pass
return AutoComplete
然後用:
TextAutoComplete = completefactory(TextCtrl)
PriceAutoComplete = completefactory(PriceCtrl)
在這取決於你想要達到的目標。另一方面,你的課怎麼看,說不定自動完成是爲了混合,所以你可以定義TextAutoComplete
:
class TextAutocomplete(TextCtrl, AutoComplete):
pass
您可以修改__bases__
元組。例如,你可以添加一個基類:
AutoComplete.__bases__ += (PriceCtrl,)
但一般我會盡量避免這種黑客,它很快就創建了一個可怕的混亂。
您可以使用多重繼承了這一點:
class AutoCompleteBase(object):
# code for your class
# remember to call base implementation with super:
# super(AutoCompleteBase, self).some_method()
class TextAutoComplete(AutoCompleteBase, TextCtrl):
pass
class PriceAutoComplete(AutoCompleteBase, PriceCtrl):
pass
此外,還有一元類的選項:
class BasesToSeparateClassesMeta(type):
"""Metaclass to create a separate childclass for each base.
NB: doesn't create a class but a list of classes."""
def __new__(self, name, bases, dct):
classes = []
for base in bases:
cls = type.__new__(self, name, (base,), dct)
# Need to init explicitly because not returning a class
type.__init__(cls, name, (base,), dct)
classes.append(cls)
return classes
class autocompletes(TextCtrl, PriceCtrl):
__metaclass__ = BasesToSeparateClassesMeta
# Rest of the code
TextAutoComplete, PriceAutoComplete = autocompletes
但是我還是建議類工廠的做法已經表明,一個水平的縮進真的不是什麼大問題。
我在想類似的路線,但它需要我縮進整個代碼,正如我所說的許多行,異議看起來微不足道,但我希望我不必縮進它 – 2009-08-26 12:28:18
不縮進:聲明隱藏的類在_TextAutoComplete等模塊的頂層,然後使用工廠。 – u0b34a0f6ae 2009-08-26 12:39:10
@Auurag,在塊模式或sed中使用vim,它很容易重新使用(你應該學會如何做到這一點,在python編程時它非常有用) – tonfa 2009-08-26 12:54:54