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 >>> Cheers, Ryan -- Ryan Kelly http://www.rfk.id.au | This message is digitally signed. Please visit r...@rfk.id.au | http://www.rfk.id.au/ramblings/gpg/ for details
signature.asc
Description: This is a digitally signed message part
-- http://mail.python.org/mailman/listinfo/python-list