A modest indentation proposal
Quinn Dunkan
quinn at chunder.ugcs.caltech.edu
Mon Dec 3 17:37:13 EST 2001
On Mon, 3 Dec 2001 11:23:09 +0100, Andreas Kostyrka <andreas at mtg.co.at> wrote:
>> The latest changes in 2.2 do a lot to address this, I think. At the cost
>> of two kinds of classes and method lookup rules and a semi smalltalk style
>Well, old style classes will be depracted some time in the future. Being so
>fundamental as it is, it will take a long time.
I'd be kind of surprised if we ever get rid of classic classes. If you think
there was a lot of noise about integer division a while back...
While premature optimization may be the root of all evil, I think maintaining
backward compatibility while trying to "fix" old mistakes is another. You
just keep accumulating gunk.
>> Since new magic attributes seem to pop up every day, what about existing
>> __getattr__-using code that had all the holes patched up, but is now going
>> to explode because suddenly python wants to look up an __eq__ method where
>> it never did before?
>well, I personally prefer this design:
>def __getattr__(self,k):
> # special ones we need to deal with.
> if k=="__repr__":
> pass
> elif k.startswith("__"):
> raise AttributeError,k
> else:
> # deal here with the "normal" stuff
> pass
Yeah, but that won't help much for delegation, like:
def __getattr__(self, k):
return getattr(self.__data, k)
Oh wait! What if '__data' is a list (and we're not in 2.2 yet)? Now we need:
def __len__(self):
return len(self.__data)
def __delitem__(self, k):
del self.__data[k]
... etc. ...
Or what if __getattr__ is supposed to force a lazy object? Now they all need
to be:
def __getattr__(self, k):
self.__force() # handle memoization etc.
return getattr(self.__data, k)
def __len__(self):
self.__force()
return len(self.__data)
def __del__(self):
pass # *don't* force!
def __cmp__(self, other):
self.__force()
return cmp(self.__data, other)
... etc. ...
I solved the above with:
class Lazy_attr:
def __init__(self, attrs):
'attrs is [(f_to_set_attr1_attr2, (attr1, attr2))]'
self.__attrs = list(attrs)
def __getattr__(self, attr):
for i in range(len(self.__attrs)):
f, attrs = self.__attrs[i]
if attr in attrs:
f()
del self.__attrs[i]
return getattr(self, attr)
else:
raise AttributeError(attr)
... where f() is expected to set the attribute, thus avoiding the __getattr__
overhead in subsuquent lookups.
More information about the Python-list
mailing list