In article <[EMAIL PROTECTED]>,
Toby Dickenson  <[EMAIL PROTECTED]> wrote:
>On Fri, 19 Apr 2002 15:28:52 +0000 (UTC), [EMAIL PROTECTED] ()
>>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):
        return obj.__dict__[name]
    except KeyError: pass
    objclass = obj.__class__
        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):
   = name

    class B(C):
        def __of__(self, parent):
            return C( + ' (in object %s)' %

    class A(C):
        b = B('b in the class')

    a = C('a')
    b = B('b')
    a.b = b
    print 'a.b = %s' %
    print 'real a.b = %s' % getrealattr(a, 'b').name

    a = A('a')
    print 'a.b = %s' %
    print 'real a.b = %s' % getrealattr(a, 'b').name

    print getrealattr(a, 'c', None)

Julien Jalon

Zope-Dev maillist  -  [EMAIL PROTECTED]
**  No cross posts or HTML encoding!  **
(Related lists - )

Reply via email to