From the Python 2.7 data model:
A class has a namespace implemented by a dictionary object. Class attribute references are translated to lookups in this dictionary, e.g.,
C.x
is translated toC.__dict__["x"]
(although for new-style classes in particular there are a number of hooks which allow for other means of locating attributes).
OK, so if I do this:
class SpecialDict(object):
... special logic ...
class SomeClass(object):
def _asdict(self):
return SpecialDict(self)
__dict__ = property(_asdict)
what mapping methods or other magic methods that mimic container types need to be present in SpecialDict
? Is it just __getitem__
or are there others?
The SomeClass
here is simplified from another question I had, reproduced here just so this question stands alone:
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