這裏是你如何可以通過多重繼承解決DRY問題。不幸的是,它不能很好地與__slots__
(它導致編譯時TypeError
s),所以我不得不離開了。希望__dict__
值不會爲您的用例浪費太多內存。
class Named(object):
"""Named object mix-in. Not useable directly."""
def __setattr__(self, name, value):
if hasattr(self, name):
raise AttributeError(
"%r object attribute %r is read-only" %
(self.__class__.__name__, name))
else:
raise AttributeError(
"Cannot add attribute %r to %r object" %
(name, self.__class__.__name__))
def __new__(cls, name, *args):
self = super(Named, cls).__new__(cls, *args)
super(Named, self).__setattr__('_name', name)
return self
def __str__(self): # override string conversion to be name
return self._name
__repr__ = __str__
class NamedInt(Named, int):
"""NamedInt class. Constructor will return a NamedLong if value is big."""
def __new__(cls, name, *args):
value = int(*args) # will raise an exception on invalid arguments
if isinstance(value, int):
return super(NamedInt, cls).__new__(cls, name, value)
elif isinstance(value, long):
return NamedLong(name, value)
class NamedLong(Named, long):
"""Nothing to see here."""
pass
很好的答案,但不處理'NamedInt('HexBased','deadbeef',16)'。 – martineau
嗯,好點。我認爲它可以用可變參數修復。我會編輯來做到這一點。 – Blckknght
感謝您的修復。在這個和@ekksun的回答之間很難做出決定,因爲兩者都很好地解決了DRY問題 - 但最終選擇了這一個,因爲它是最直接,最容易理解的恕我直言。順便說一句,有可能爲'NamedInt'子類添加'__slots__'屬性(正如eryksun所做的那樣),這似乎滿足了對可能更常見的'int'情況的需求(並且_is_是用於預期用途的重要特徵)。 – martineau