How can I make an existing object read-only?
Alex Martelli
aleaxit at yahoo.com
Tue Oct 5 02:13:19 EDT 2004
Eli Stevens (WG.c) <listsub at 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
More information about the Python-list
mailing list