Private variables
Ryan Kelly
ryan at rfk.id.au
Wed Sep 1 22:22:21 EDT 2010
On Thu, 2010-09-02 at 12:06 +1000, Ryan Kelly wrote:
> On Thu, 2010-09-02 at 11:10 +1000, Rasjid Wilcox wrote:
> > Hi all,
> >
> > I am aware the private variables are generally done via convention
> > (leading underscore), but I came across a technique in Douglas
> > Crockford's book "Javascript: The Good Parts" for creating private
> > variables in Javascript, and I'd thought I'd see how it translated to
> > Python. Here is my attempt.
> >
> > def get_config(_cache=[]):
> > private = {}
> > private['a'] = 1
> > private['b'] = 2
> > if not _cache:
> > class Config(object):
> > @property
> > def a(self):
> > return private['a']
> > @property
> > def b(self):
> > return private['b']
> > config = Config()
> > _cache.append(config)
> > else:
> > config = _cache[0]
> > return config
> >
> > >>> c = get_config()
> > >>> c.a
> > 1
> > >>> c.b
> > 2
> > >>> c.a = 10
> > Traceback (most recent call last):
> > File "<string>", line 1, in <fragment>
> > AttributeError: can't set attribute
> > >>> dir(c)
> > ['__class__', '__delattr__', '__dict__', '__doc__', '__format__',
> > '__getattribute__', '__hash__', '__init__', '__module__', '__new__',
> > '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
> > '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b']
> > >>> d = get_config()
> > >>> d is c
> > True
> >
> > I'm not really asking 'is it a good idea' but just 'does this work'?
> > It seems to work to me, and is certainly 'good enough' in the sense
> > that it should be impossible to accidentally change the variables of
> > c.
> >
> > But is it possible to change the value of c.a or c.b with standard
> > python, without resorting to ctypes level manipulation?
>
> It's not easy, but it can be done by introspecting the property object
> you created and munging the closed-over dictionary object:
>
> >>> c = get_config()
> >>> c.a
> 1
> >>> c.__class__.__dict__['a'].fget.func_closure[0].cell_contents['a'] = 7
> >>> c.a
> 7
> >>>
Heh, and of course I miss the even more obvious trick of just clobbering
the property with something else:
>>> c.a
1
>>> setattr(c.__class__,"a",7)
>>> c.a
7
>>>
Ryan
--
Ryan Kelly
http://www.rfk.id.au | This message is digitally signed. Please visit
ryan at rfk.id.au | http://www.rfk.id.au/ramblings/gpg/ for details
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part
URL: <http://mail.python.org/pipermail/python-list/attachments/20100902/acbb6988/attachment-0001.sig>
More information about the Python-list
mailing list