Re: How can I make an existing object read-only?

From: Alex Martelli (aleaxit_at_yahoo.com)
Date: 10/05/04


Date: Tue, 5 Oct 2004 08:13:19 +0200

Eli Stevens (WG.c) <listsub@wickedgrey.com> wrote:
   ...
> def ReadWrite(self):
> print "ReadWrite"
> self._CurrentState__setattr__ = self._readWriteSetattr
>
> def ReadOnly(self):
> print "ReadOnly"
> self._CurrentState__setattr__ = self._readOnlySetattr
>
> def __setattr__(self, name, value):
> self._CurrentState__setattr__(name, value)
   ...
> self.__setattr__ = self._readOnlySetattr
>
> Doesn't DWIM. ;) Hence the _CurrentState__setattr__ hack. Is this
> pythonic? Dunno. Thoughts?
>
> I also don't know which would be faster between the proxy and having an
> extra level of indirection in __setattr__. I would guess it would
> depend on if you do more reads or writes in the tight loops. If your
> code is read-heavy, this might actually be a win.
>
> Of course, if you are _really_ concerned with performance, you might
> just turn the whole protection thing off when in production.

...or implement it by changing the object's *class*...:

class RO_class(TrueClass):
    def makeReadWrite(self): self.__class__ = TrueClass
    def __setattr__(self, n, v=''): raise AttributeError, n
    __delattr__ = __setattr__

def makeReadOnly(obj): obj.__class__ = RO_class

This is a very Pythonic approach to dealing with an object that exists
in two 'states', each rather persistent and with different behavior; it
is better performing and neater than using an obj._state and having 'if
self._state: ... else: ...' statements strewn around.

Your approach (switching boundmethods instead of a passive state flag or
the class itself) is somewhere in-between -- it may require indirection
when special methods are involved (since, in the new object model,
Python looks special methods up per-class, not per-instance), it may
require switching more than one method (more flexible if needed, but
otherwise boilerplatey if you always switch methods as a group).

As I recall, the early prototypes for the new object model (pre-release
2.2's) had obj.__class__ as read-only; it was changed to read/write
specifically to enable this idiom -- a fact which appears to me to
support the contention that this IS a highly Pythonic approach, not just
a hack which accidentally happens to work...

Alex



Relevant Pages

  • multiprocessing question/error
    ... After switching to python 2.6.1 I am having some problems with the same code. ... def calcula: ... Exception in thread Thread-1: ...
    (comp.lang.python)
  • multiprocessing question/error
    ... After switching to python 2.6.1 I am having some problems with the same code. ... def calcula: ... Exception in thread Thread-1: ...
    (comp.lang.python)
  • Re: Method Underscores?
    ... My impression was that underscores are supposed ... They are used to indicate special methods used by Python ... leading and trailing underscores) but then there's ...
    (comp.lang.python)
  • Re: special method in module
    ... > can have modules special methods? ... very good reasons. ... module that's a transparent proxy to some external system might be. ... Python always works better if you use it to write Python code...) ...
    (comp.lang.python)
  • Re: Confusion About Classes
    ... there are no variables in python (yea I know others will say otherwise ... def setData: ... Not all underscores method names are unnecessary. ... special methods and are part of python(later you will see they can be ...
    (comp.lang.python)