setattr() oddness

Dieter Maurer dieter at handshake.de
Wed Jan 20 01:41:13 EST 2010


Steven D'Aprano <steven at REMOVE.THIS.cybersource.com.au> writes on 18 Jan 2010 06:47:59 GMT:
> On Mon, 18 Jan 2010 07:25:58 +0100, Dieter Maurer wrote:
> 
> > Lie Ryan <lie.1296 at gmail.com> writes on Sat, 16 Jan 2010 19:37:29 +1100:
> >> On 01/16/10 10:10, Sean DiZazzo wrote:
> >> > Interesting.  I can understand the "would take time" argument, but I
> >> > don't see any legitimate use case for an attribute only accessible
> >> > via getattr().  Well, at least not a pythonic use case.
> >> 
> >> mostly for people (ab)using attributes instead of dictionary.
> > 
> > Here is one use case:
> > 
> >  A query application. Queries are described by complex query objects.
> >  For efficiency reasons, query results should be cached. For this, it is
> >  not unnatural to use query objects as cache keys. Then, query objects
> >  must not get changed in an uncontrolled way. I use "__setattr__" to
> >  control access to the objects.
> 
> 
> (1) Wouldn't it be more natural to store these query keys in a list or 
> dictionary rather than as attributes on an object?
> 
> e.g. instead of:
> 
> cache.__setattr__('complex query object', value)
> 
> use:
> 
> cache['complex query object'] = value

Few will use "cache.__setattr__(...)" but "cache.attr = ..." which
is nicer than "cache['attr'] = ...".

Moreover, it is not the cache but the query of which I want to protect
modification. My cache indeed uses "cache[query_object] = ...".
But I want to prevent "query_object" from being changed after a potential
caching.



> (2) How does __setattr__ let you control access to the object? If a user 
> wants to modify the cache, and they know the complex query object, what's 
> stopping them from using __setattr__ too?

In my specific case, "__setattr__" prevents all modifications via attribute
assignment. The class uses "__dict__" access to set attributes when
it knows it is still safe.

Of course, this is no real protection against attackers (which could
use "__dict__" as well). It only protects against accidental change
of query objects.


Meanwhile, I remembered a more important use case for "__setattr__":
providing for transparent persistancy. The "ZODB" (Zope Object DataBase)
customizes "__setattr__" in order to intercept object modifications
and register automatically that the change needs to be persisted at
the next transaction commit.


Dieter



More information about the Python-list mailing list