我想用类似的东西collections.namedtuple
,它很好地强制了不变性并促进了简单的值类,但它不允许子类化;例如我想做类似下面的事情添加额外的只读属性 https://stackoverflow.com/questions/2193009/extend-python-namedtuple-with-many-properties:
from collections import namedtuple
class Foo(namedtuple('Foo','foo')):
@property
def antifoo(self):
return -self.foo
class Bar(Foo):
""" ARGH: somehow we add a 'bar' field """
@property
def inversebar(self):
return 1.0/bar
唯一的问题是没有添加额外属性的机制。所以我查看了结果collections.namedtuple('Test','foo bar baz', verbose=True)
并根据我自己的目的对其进行了调整:
from collections import OrderedDict
from operator import itemgetter as _itemgetter
class Foo(tuple):
__slots__ = ()
_fields = ('foo',)
_nargs = 1
_repr_format = '(foo=%r)'
foo = property(_itemgetter(0), doc='Alias for field number 0')
def __new__(_cls, foo):
return tuple.__new__(_cls, (foo,))
@classmethod
def _make(cls, iterable, new=tuple.__new__, len=len):
'Make a new Foo object from a sequence or iterable'
result = new(cls, iterable)
if len(result) != cls._nargs:
raise TypeError('Expected 1 argument, got %d' % len(result))
return result
def _replace(self, **kwds):
'Return a new {typename} object replacing specified fields with new values'
result = self._make(map(kwds.pop, self._fields, self))
if kwds:
raise ValueError('Got unexpected field names: %r' % kwds.keys())
return result
def __repr__(self):
'Return a nicely formatted representation string'
return self.__class__.__name__ + self._repr_format % self
def _asdict(self):
'Return a new OrderedDict which maps field names to their values.'
return OrderedDict(zip(self._fields, self))
__dict__ = property(_asdict)
def __getstate__(self):
'Exclude the OrderedDict from pickling'
pass
@property
def antifoo(self):
return -self.foo
class Bar(Foo):
_fields = ('foo','bar')
_nargs = 2
_repr_format = '(foo=%r, bar=%r)'
bar = property(_itemgetter(1), doc='Alias for field number 1')
def __new__(_cls, foo, bar):
return tuple.__new__(_cls, (foo, bar))
@property
def inversebar(self):
return 1.0/self.bar
This seems正常工作,但是可以吗,还是我犯了一个严重的错误?