[Python-Dev] Meta-reflections
Samuele Pedroni
pedroni@inf.ethz.ch
Fri, 22 Feb 2002 01:38:27 +0100
From: Tim Peters <tim.one@comcast.net>
> [Tim]
> > Slots were definitely intended as a memory optimization, and the ways in
> > which they don't act like "regular old attributes" are at best warts.
>
> [Samuele Pedroni]
> > I see, but it seems that the only way to coherently and transparently
> > remove the warts implies that the __dict__ of a new-style class
> > instance with slots should be tied with the instance and cannot
> > be anymore a vanilla dict. Something only Guido can rule about.
>
> He'll be happy to <wink>. Optimizations aren't always wart-free, and then
> living with warts is a price paid for benefiting from the optimization. I'm
> sure Guido would consider it "a bug" if slots are ignored by the pickling
> mechanism, but wouldn't for an instant consider it "a bug" that the set of
> slots in effect when a class is created can't be dynamically expanded later
> (this latter is more a sensible restriction than a wart, IMO -- and likely
> in Guido's too).
>
I was thinking along the line of the C equiv of this:
[Yup the situation of a subclass of a class with slots
is more relevant]
class C(object):
__slots__ = ['_a']
class D(C): pass
def allslots(cls):
mro = list(cls.__mro__)
mro.reverse()
allslots = {}
for c in mro:
cdict = c.__dict__
if '__slots__' in cdict:
for slot in cdict['__slots__']:
allslots[slot] = cdict[slot]
return allslots
class slotdict(dict):
__slots__ = ['_inst','_allslots']
def __init__(self,inst,allslots):
self._inst = inst
self._allslots = allslots
def __getitem__(self,k):
if self._allslots.has_key(k):
# self _allslots should be reachable as
self._inst.__class__.__allslots__
# AttributeError should become a KeyError ?
return self._allslots[k].__get__(self._inst)
else:
return dict.__getitem__(self,v)
def __setitem__(self,k,v):
if self._allslots.has_key(k):
# self _allslots should be reachable as
self._inst.__class__.__allslots__
# AttributeError should become a KeyError ?
return self._allslots[k].__set__(self._inst,v)
else:
return dict.__setitem__(self,v)
# other methods accordingly
d=D()
d.__dict__ = slotdict(d,allslots(D)) # should be so automagically
# allslots(D) should be probably accessible as d.__class__.__allslots__
# for transparency C.__dict__ should not contain any slot descr
# __allslots__ should be readonly and disallow rebinding
# d.__dict__ should disallow rebinding
# c =C() ; c.__dict__ should return a proxy dict lazily or even more so ...
Lots of things to rule about and trade-offs to consider.
the-more-it's-arbitrary-the-more-you-need-_one_-ruler-ly y'rs - Samuele.