undesired interraction between property and __setattr__

dman dsh8290 at rit.edu
Sat Jan 26 17:23:06 EST 2002


On Sat, Jan 26, 2002 at 09:37:54PM +0000, Alex Martelli wrote:
| dman wrote:
|         ...
| >     def __setattr__( self , name , value ) :
| >         if name == "_s" :
| >             self.__dict__[name] = value
| >         elif name in self.__class__.__dict__ :
| >             self.__dict__[ name ] = self.__class__.__dict__[ name ]
| >             self.__dict__[ name ].__set__( self , value )
| >         else :
| >             print name , "=>" , value
| >             setattr( self._s , name , value )
|         ...
| > Is this the proper/ideal solution, or is there something I'm missing,
| > or is this a bug in python?
| 
| I think a somewhat more natural way to code this __setattr__ might be:
| 
|     def __setattr__( self , name , value ) :
|         if name == "_s" or hasattr(
|             getattr(self.__class__, name, None), '__set__'):
|                 object.__setattr__(self, name, value)
|         else :
|             print name , "=>" , value
|             setattr( self._s , name , value )
| 
| i.e.: if the name is _s, OR is the name of a data attribute defined in the
| current class, THEN use the normal way to set the attribute as defined by
| class object (which includes property setting or stashing in self.__dict__),
| ELSE print something and set the name/value attribute in self._s instead.

Thanks.  This is better since (with the proper __getattr__, which has
no unexpected clash) it works with inherited properties as well.

| I find the nested combination of hasattr and setattr here a bit hard to
| follow, though.  My personal preference would be something like:
| 
|     def __setattr__( self , name , value ) :
|         try: setter = self.__class__.name.__set__
                                      ^^^^^^

This would only work in the case
    name == "name"

(unless there's some new magic I'm unaware of :-))

It also isn't recursive, so it wouldn't handle inherited properties.

|         except AttributeError:
|             if name == '_s':
|                 self.__dict__['_s'] = value
|             else:
|                 print name , "=>" , value
|                 setattr( self._s , name , value )
|         else: setter(self, value)
| 
| but it's an issue of personal stylistic preference.


-D

-- 

If Microsoft would build a car...
... Occasionally your car would die on the freeway for no reason. You
would have to pull over to the side of the road, close all of the car
windows, shut it off, restart it, and reopen the windows before you
could continue. For some reason you would simply accept this.





More information about the Python-list mailing list