In article <6ae0cu8p0j6a7grmcdneeujvtlbpju26e1@4ax.com>, Toby Dickenson <tdickenson@geminidataloggers.com> wrote:
On Fri, 19 Apr 2002 15:28:52 +0000 (UTC), jalon@dev.in.nuxeo.com () wrote:
It seems there is no way to get the real 'b' attribute from a, i.e. the B instance set at the line "a.b = B()"
Thats exactly right. your __of__ method means that *any* time you try to take a B object out of an A, you get a C object instead of a B.
try a.__dict__['b']
That's not a good solution since the b attribute can be defined in the classes of a... With some tries, I think I got the solution: _nodefault = [] def getrealattr(obj, name, default = _nodefault): try: return obj.__dict__[name] except KeyError: pass objclass = obj.__class__ try: attr = getattr(objclass, name) if hasattr(attr, '__of__'): # a trick from extension class: # whenever you get a class attribute, # you will get a Python Method # im_func get the function if it is a # method and the real object if not return attr.im_func return attr except AttributeError: if default is _nodefault: raise return default if __name__ == '__main__': # Tests from Acquisition import Implicit class C(Implicit): def __init__(self, name): self.name = name class B(C): def __of__(self, parent): return C(self.name + ' (in object %s)' % parent.name).__of__(parent) class A(C): b = B('b in the class') a = C('a') b = B('b') a.b = b print 'a.b = %s' % a.b.name print 'real a.b = %s' % getrealattr(a, 'b').name a = A('a') print 'a.b = %s' % a.b.name print 'real a.b = %s' % getrealattr(a, 'b').name print getrealattr(a, 'c', None) -- Julien Jalon http://www.nuxeo.com/