On 24 Jan 2006 09:30:00 -0800, [EMAIL PROTECTED] wrote: >some time after posting my `Linkdict recipe`__ to aspn__ >-- basically, a dictionary with run-time delegational >lookup, but this is not important here -- i thought gee >that would be fun to make such a customized dictionary >thingie an instance dictionary, and get some custom >namespace behavior out of that. > >.. __: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/465748 >.. __: http://aspn.activestate.com/ > >here is a simplified example: first, the customized >dictionary class and a test:: > > > class CustomDict( dict ): > > defaultValue = 'THIS ITEM NOT AVAILABLE' > > def __getitem__( self, name ): > try: > return super( CustomDict, self ).__getitem__( name ) > except KeyError: > return self.defaultValue > > def __contains__( self, name ): > return True > > def has_key( self, name ): > return True > > print '----------------------------------------' > cd = CustomDict( foo = 'bar' ) > print cd[ 'foo' ] > print cd[ 'bar' ] > print 'bar' in cd > print cd.has_key( 'bar' ) > >this gives us:: > > ---------------------------------------- > bar > THIS ITEM NOT AVAILABLE > True > True > >so it appears to work. note that we may have failed to >implement all the conceivable ways to test for >membership (such as searching through ``keys()``) or to >retrieve a value for a given key. more on that below. >now for the class to utilize this definition:: > > class X( object ): > > def __init__( self ): > self.__dict__ = CustomDict( foo = 'bar' ) > >and the test code for that:: > > print '----------------------------------------' > x = X() > print x.__dict__[ 'foo' ] > print x.__dict__[ 'bar' ] > print x.foo > print x.bar > >which yields:: > > ---------------------------------------- > bar > THIS ITEM NOT AVAILABLE > bar > > Traceback (most recent call last): > File "C:\home\projects\__svn__\sundry\#.py", line 39, in ? > print x.bar > AttributeError: 'X' object has no attribute 'bar' > >ok. so the custom dict *basically* works as expected, >since it does successfully make ``x.foo`` available -- >no surprise here. unfortunately, looking up ``x.bar``, >which should really return the default value string, >causes an ``AttributeError`` to be raised. > >now of course given the short definition of >``CustomDict``, perhaps there is an essential lookup >method that has not been overwritten but that is >internally used for attribute lookup. however, i >carefully tested my actual class (from the recipe >mentioned above) and also compared the methods defined >there against the standard ``dict()`` interface, and >nothing of importance appeared to be missing. i also >tried to bind the dictionary to the instance earlier, in >``__new__``, to no avail. am i missing something here? > Well, if you compare with the following, maybe something will fall into place?
>>> class CustomDict( dict ): ... defaultValue = 'THIS ITEM NOT AVAILABLE' ... def __getitem__( self, name ): ... try: ... return super( CustomDict, self ).__getitem__( name ) ... except KeyError: ... return self.defaultValue ... def __contains__( self, name ): ... return True ... def has_key( self, name ): ... return True ... >>> class X( object ): ... __dict__ = property(lambda self:self._dict) ... def __getattr__(self, attr): return self.__dict__[attr] ... def __init__( self ): ... self._dict = CustomDict( foo = 'bar' ) ... >>> x = X() >>> print x.__dict__['foo'] bar >>> print x.__dict__['bar'] THIS ITEM NOT AVAILABLE >>> print x.foo bar >>> print x.bar THIS ITEM NOT AVAILABLE Additional data points: >>> x.__dict__ {'foo': 'bar'} >>> X.__dict__ <dictproxy object at 0x02E814C4> >>> X.__dict__['__dict__'] <property object at 0x02EEF70C> and >>> class Y(object): ... def _getdict(self): print '_getdict'; return self._dict ... __dict__=property(_getdict) ... def __init__( self ): ... self._dict = CustomDict( foo = 'bar' ) ... >>> y = Y() >>> y.__dict__ _getdict {'foo': 'bar'} >>> y._dict {'foo': 'bar'} >>> y.foo Traceback (most recent call last): File "<stdin>", line 1, in ? AttributeError: 'Y' object has no attribute 'foo' >>> def ga(self, attr): print '__getattr__(%s)'%attr; return >>> self.__dict__[attr] ... >>> Y.__getattr__ = ga >>> y.foo __getattr__(foo) _getdict 'bar' Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list