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 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