S
Steven W. Orr
I just discovered descriptors but what I want to do isn't working right.
I hope this isn't too long. :-(
Here's what I have that works:
class C(object):
def g(self):
print "dir(g):",dir(self.g)
def f(self, ss):
print "ss = ", ss
cc = C()
cc.ff = f.__get__(C,cc)
cc.ff('Round 3')
And when I run it, it prints out:
ss = Round 3
That's the part that works. I'm trying to use the above construct to implement a
new kind of dict().
The idea is that I want to create a dict that knows about certain values that
can have dependencies on other values. If you change a value that is a
dependency of another value within the dict, then the target value will
automatically recompute itself. In the example below, the value of the key
"range" is dependent on the value of the key "stop".
When I run the code, the function recalc_range seems to be successfully saved as
a bound method. (The save happens in AddDep) But then when I try to invoke the
saved bound method, it yells at me that the arg to __getitem__ is of the wrong type.
Does anyone see what I did wrong?
class BalancedDict(dict):
def __init__( self, initval={}, depDesc=None ):
dict.__init__(self)
self.target = []
self.deplist = []
self.recalc_f = []
self.addDep( depDesc )
if isinstance(initval, dict):
dict.update(self, initval)
def __setitem__(self, key, value): # setting a keyword
dict.__setitem__(self, key, value)
for ii, deps in enumerate(self.deplist):
if key in deps:
print '__setitem__:recalc_f[%d]'%ii,self.recalc_f[ii]
print '__setitem__:targ:',self.target[ii]
print '__setitem__:deplist:',self.deplist[ii]
self.recalc_f[ii](self.target[ii],self.deplist[ii])
def addDep(self, depDesc=None):
if not depDesc:
return
for jj in depDesc:
self.target.append(jj[0])
self.deplist.append(jj[1])
self.recalc_f.append(None)
idx = len(self.recalc_f) - 1
self.recalc_f[idx] = jj[2].__get__(BalancedDict, self)
print 'addDep:self.recalc_f[%d]:'%idx, self.recalc_f[idx]
if __name__ == "__main__":
import pprint
def recalc_range(self, target, deplist):
print 'recalc_range:type(self):', type(self), "self:",self
print 'recalc_range:target:', target
print 'recalc_range:deplist:', deplist
stop = None
for ii in deplist:
if ii == 'stop':
print "ii:",ii
print "self:", self, type(self)
stop = self.__getitem__(ii)
if ( isinstance( stop, int ) ):
self.__setitem__( self[target], range( stop ) )
pp = pprint.PrettyPrinter()
dd = BalancedDict()
print 'dd: Init'
pp.pprint(dd)
dd.addDep([['range', ['stop'], recalc_range]])
dd['stop'] = 40
print 'dd: After start stop and step'
pp.pprint(dd)
C:\Users\Steve\Documents\PythonSamples>python -i vfunc3.py
dd: Init
{}
addDep:self.recalc_f[0]: <bound method ?.recalc_range of <class
'__main__.BalancedDict'>>
__setitem__:recalc_f[0] <bound method ?.recalc_range of <class
'__main__.BalancedDict'>>
__setitem__:targ: range
__setitem__:deplist: ['stop']
recalc_range:type(self): <type 'type'> self: <class '__main__.BalancedDict'>
recalc_range:target: range
recalc_range:deplist: ['stop']
ii: stop
self: <class '__main__.BalancedDict'> <type 'type'>
Traceback (most recent call last):
File "vfunc3.py", line 55, in <module>
dd['stop'] = 40
File "vfunc3.py", line 20, in __setitem__
self.recalc_f[ii](self.target[ii],self.deplist[ii])
File "vfunc3.py", line 46, in recalc_range
stop = self.__getitem__(ii)
TypeError: descriptor '__getitem__' requires a 'dict' object but received a 'str'
--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
I hope this isn't too long. :-(
Here's what I have that works:
class C(object):
def g(self):
print "dir(g):",dir(self.g)
def f(self, ss):
print "ss = ", ss
cc = C()
cc.ff = f.__get__(C,cc)
cc.ff('Round 3')
And when I run it, it prints out:
ss = Round 3
That's the part that works. I'm trying to use the above construct to implement a
new kind of dict().
The idea is that I want to create a dict that knows about certain values that
can have dependencies on other values. If you change a value that is a
dependency of another value within the dict, then the target value will
automatically recompute itself. In the example below, the value of the key
"range" is dependent on the value of the key "stop".
When I run the code, the function recalc_range seems to be successfully saved as
a bound method. (The save happens in AddDep) But then when I try to invoke the
saved bound method, it yells at me that the arg to __getitem__ is of the wrong type.
Does anyone see what I did wrong?
class BalancedDict(dict):
def __init__( self, initval={}, depDesc=None ):
dict.__init__(self)
self.target = []
self.deplist = []
self.recalc_f = []
self.addDep( depDesc )
if isinstance(initval, dict):
dict.update(self, initval)
def __setitem__(self, key, value): # setting a keyword
dict.__setitem__(self, key, value)
for ii, deps in enumerate(self.deplist):
if key in deps:
print '__setitem__:recalc_f[%d]'%ii,self.recalc_f[ii]
print '__setitem__:targ:',self.target[ii]
print '__setitem__:deplist:',self.deplist[ii]
self.recalc_f[ii](self.target[ii],self.deplist[ii])
def addDep(self, depDesc=None):
if not depDesc:
return
for jj in depDesc:
self.target.append(jj[0])
self.deplist.append(jj[1])
self.recalc_f.append(None)
idx = len(self.recalc_f) - 1
self.recalc_f[idx] = jj[2].__get__(BalancedDict, self)
print 'addDep:self.recalc_f[%d]:'%idx, self.recalc_f[idx]
if __name__ == "__main__":
import pprint
def recalc_range(self, target, deplist):
print 'recalc_range:type(self):', type(self), "self:",self
print 'recalc_range:target:', target
print 'recalc_range:deplist:', deplist
stop = None
for ii in deplist:
if ii == 'stop':
print "ii:",ii
print "self:", self, type(self)
stop = self.__getitem__(ii)
if ( isinstance( stop, int ) ):
self.__setitem__( self[target], range( stop ) )
pp = pprint.PrettyPrinter()
dd = BalancedDict()
print 'dd: Init'
pp.pprint(dd)
dd.addDep([['range', ['stop'], recalc_range]])
dd['stop'] = 40
print 'dd: After start stop and step'
pp.pprint(dd)
C:\Users\Steve\Documents\PythonSamples>python -i vfunc3.py
dd: Init
{}
addDep:self.recalc_f[0]: <bound method ?.recalc_range of <class
'__main__.BalancedDict'>>
__setitem__:recalc_f[0] <bound method ?.recalc_range of <class
'__main__.BalancedDict'>>
__setitem__:targ: range
__setitem__:deplist: ['stop']
recalc_range:type(self): <type 'type'> self: <class '__main__.BalancedDict'>
recalc_range:target: range
recalc_range:deplist: ['stop']
ii: stop
self: <class '__main__.BalancedDict'> <type 'type'>
Traceback (most recent call last):
File "vfunc3.py", line 55, in <module>
dd['stop'] = 40
File "vfunc3.py", line 20, in __setitem__
self.recalc_f[ii](self.target[ii],self.deplist[ii])
File "vfunc3.py", line 46, in recalc_range
stop = self.__getitem__(ii)
TypeError: descriptor '__getitem__' requires a 'dict' object but received a 'str'
--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net