[Python-Dev] Re: Writing a mutable object problem with __setattr__
Aleksandar Totic
atotic@osafoundation.org
Tue, 25 Feb 2003 08:55:45 -0800
Guido van Rossum wrote:
> Aleks Totic wrote:
>>I am trying to create a mutable object for a persistent object
>>database, and I've ran into a problem. The semantics are:
>>
>>Object gets created as a 'Swizzle'. Swizzle is a stub that
>>intercepts any attempt to access object properties. When code
>>tries to access any of swizzle's properties, the swizzle should
>>automatically mutate into the stored object, by changing its
>>class and properties.
>
> .....................................
>
>>With the __set/get/del/attr__ traps this seemed feasible in
>>Python. But it turns out to be trickier than I've thought, my
>>naive implementation is not working.
>>
>>What happens is:
>>swizzle.__getattr__() gets called
>> calls swizzle.load()
>> swizzle.__class__ = stored_class
>> swizzle.__dict__ = stored_data
>> calls getattr(self, attr_name)
>> calls swizzle.__getattr__() gets called
>> and I enter an infinite loop and blow the stack
>>
>>
>>I've tried many different approaches:
>>- Swizzle inheriting from object (so that I can call super
>>methods directly). This one would not let me assign into the
>>__class__
>
> In Python 2.2.2 you can set __class__, as long as __class__ has a
> compatible instance lay-out (at the C implementation level).
This is the part where I am confused. How do I know if something
is an old or new style object? Do new-style objects derive from
built-in types (object/dict..)
> With new-style objects, you can use __getattribute__ instead of
> __getattr__ for more control (and also more opportunities to blow the
> stack :-).
>
>.................................
>
>> def __setattr__(self, name, value):
>> """ setattr passes class & dict because these are called
>> when we are mutating the object """
>> print "swizzle setattr called"
>> if (name == '__class__' or name == '__dict__' or name ==
>>'oid'):
>> self.__dict__[name] = value
>> return
>
>
> Ah, here's the catch. You can't implement assignment to __dict__ or
> __class__ by doing "self.__dict__[name] = value".
>
> Use new-style classes and you'll be much happier: you can invoke the
> superclass __setattr__ to do the magic.
I've tried this, but then I was unable to create any of the
old-style classes. Is there any solution that would let me mutate
an object into both? I suspect not. Then the question is:
- is there a runtime/compiling python flag to force all objects
into new-style layout? This will be the future, I think I've read
somewhere.
- how can I tell the difference between old and new programatically?
Aleks