On Dec 2, 6:13 pm, Aaron Brady <[EMAIL PROTECTED]> wrote: > On Dec 2, 6:58 pm, "Zac Burns" <[EMAIL PROTECTED]> wrote: > > > > > Sorry for the long subject. > > > I'm trying to create a subclass dictionary that runs extra init code > > on the first __getitem__ call. However, the performance of __getitem__ > > is quite important - so I'm trying in the subclassed __getitem__ > > method to first run some code and then patch in the original dict > > method for the instance to avoid even the check to see if the init > > code has been run. Various recipes using instancemethod and the like > > have failed me. > > > Curiously if __slots__ is not specified no error occurs when setting > > self.__getitem__ but the function is not overriden. If __slots__ is > > ['__getitem__'] however it complains that __getitem__ is read only. I > > do not understand that behavior. > > > -- > > Zachary Burns > > (407)590-4814 > > Aim - Zac256FL > > Production Engineer (Digital Overlord) > > Zindagi Games > > That sounds like the State Pattern, from GoF. > http://en.wikipedia.org/wiki/State_pattern > > I like the idea of 'renaming', not redefining, but reassigning methods > at different points during an object's lifetime. I often wish I had > more experience with it, and more docs talked about it. > > It's hard on memory usage, since each instance has its own function > attribute, even if there's still only one instance of the function. > Without it, the function attribute is just looked up on the class. > > Not thoroughly tested: > > >>> class A: > > ... def methA( self ): > ... print 'methA' > ... self.meth= self.methB > ... meth= methA > ... def methB( self ): > ... print 'methB' > ...>>> a= A() > >>> a.meth() > methA > >>> a.meth() > > methB
The problem with using this this pattern in the way that you've specified is that you have a potential memory leak/object lifetime issue. Assigning a bound method of an instance (which itself holds a reference to self) to another attribute in that same instance creates a kind of circular dependency that I have discovered can trip up the GC more often than not. You can subclass it as easily: class dictsubclass(dict): def __getitem__(self, keyname): if not hasattr(self, '_run_once'): self.special_code_to_run_once() self._run_once = True return super(self, dict).__getitem__(keyname) If that extra ~16 bytes associated with the subclass is really a problem: class dictsubclass(dict): def __getitem__(self, keyname): self.special_code_to_run_once() self.__class__ = dict return super(self, dict).__getitem__(keyname) But I don't think that's a good idea at all. -- http://mail.python.org/mailman/listinfo/python-list