Steven Bethard wrote:
I'd like to be able to have an instance variable that can sometimes be accessed as a property, and sometimes as a regular value, e.g. something like:
...
py> c.x is c.x # I'd like this to be False
You'd like 'c.x is c.x' to be FALSE? You can't be serious. Must be a typo.
Hmm... maybe I better give the larger context. The short answer is no, I'm serious.
I'm playing around with a mapping type that uses setdefault as suggested in http://www.python.org/moin/Python3_2e0Suggestions. The default value for a missing key is either a simple value, or a value generated from a function. If it's generated from the function, it should be generated new each time so that, for example, if the default is an empty list, d[1] and d[2] don't access the same list. This is why 'c.x is c.x' should be False if I'm using the function.
Some more context:
Before I added the ability to use a function, my code looked something like:
py> class D(dict): ... def __init__(self): ... self._default = None ... def __getitem__(self, key): ... if not key in self: ... self[key] = self._default ... return dict.__getitem__(self, key) ... def setdefaultvalue(self, value): ... self._default = value ... py> d = D() py> d[0] py> d.setdefaultvalue(0) py> d[1] 0 py> d[2] += 1 py> d {0: None, 1: 0, 2: 1}
To add the ability to use a function to create the default value, it would have been nice to leave basically the same code I already had and do something like:
py> class D(dict): ... def __init__(self): ... self._default = None ... def __getitem__(self, key): ... if not key in self: ... self[key] = self._default ... return dict.__getitem__(self, key) ... def setdefaultvalue(self, value): ... self._default = value ... def setdefaultfunction(self, func, *args, **kwds): ... self._func, self._args, self._kwds = func, args, kwds ... self._default = D._defaultfunc ... def _get(self): ... return self._func(*self._args, **self._kwds) ... _defaultfunc = property(_get) ...
Of course, this doesn't work for the reasons that I discussed, but the idea would be that D would use a regular attribute when a simple value was needed, and a property when a value had to be generated by a function each time.
The best option I guess is to rewrite this with a _getdefault() function instead of a property:
py> class D(dict): ... _undefined = object() ... def __init__(self): ... self._value = None ... self._func = self._undefined ... def __getitem__(self, key): ... if not key in self: ... self[key] = self.getdefault() ... return dict.__getitem__(self, key) ... def getdefault(self): ... if self._value is not self._undefined: ... return self._value ... if self._func is not self._undefined: ... return self._func(*self._args, **self._kwds) ... def setdefaultvalue(self, value): ... self._value = value ... self._func = self._undefined ... def setdefaultfunction(self, func, *args, **kwds): ... self._func, self._args, self._kwds = func, args, kwds ... self._value = self._undefined ...
But I was hoping to avoid having two separate attributes (self._value and self._func) when only one should have a value at any given time.
Steve
-- http://mail.python.org/mailman/listinfo/python-list