In a function, how to get the caller object ?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • popov

    In a function, how to get the caller object ?

    Look at this code:

    class C:
    def func():
    <caller_of_func >.my_attrib = 1
    func = staticmethod(fu nc)

    C.func()

    c = C()
    c.func()

    In func, I would like to get C for the first call, and c for the
    second one, to be able to add a new attribute to this object (so that
    would add the attribute either to the class object or to the
    instance). How can I do this ?
    I tried to give a look to the inspect module with no luck.
  • Bengt Richter

    #2
    Re: In a function, how to get the caller object ?

    On 3 Dec 2003 06:56:06 -0800, google@evpopov. com (popov) wrote:
    [color=blue]
    >Look at this code:
    >
    >class C:
    > def func():
    > <caller_of_func >.my_attrib = 1
    > func = staticmethod(fu nc)
    >
    >C.func()
    >
    >c = C()
    >c.func()
    >
    >In func, I would like to get C for the first call, and c for the
    >second one, to be able to add a new attribute to this object (so that
    >would add the attribute either to the class object or to the
    >instance). How can I do this ?
    >I tried to give a look to the inspect module with no luck.[/color]

    You need something other than staticmethod, that delivers an ordinary method or
    an effective classmethod depending on access via the class or an instance, e.g.,
    (not tested beyond what you see):
    (BTW, I added a value parameter to your func, for less ambiguous example results)
    [color=blue][color=green][color=darkred]
    >>> class SpecialMethod(o bject):[/color][/color][/color]
    ... def __get__(self, obj, cls):
    ... if obj is None: return self.fun.__get_ _(cls, cls)
    ... else: return self.fun.__get_ _(obj, type(obj))
    ... def __init__(self, fun):
    ... self.fun = fun
    ...[color=blue][color=green][color=darkred]
    >>> class C(object):[/color][/color][/color]
    ... def func(caller_of_ func, value=1):
    ... caller_of_func. my_attrib = value
    ... func = SpecialMethod(f unc)
    ...[color=blue][color=green][color=darkred]
    >>> C[/color][/color][/color]
    <class '__main__.C'>[color=blue][color=green][color=darkred]
    >>> C.func[/color][/color][/color]
    <bound method C.func of <class '__main__.C'>>[color=blue][color=green][color=darkred]
    >>> vars(C)[/color][/color][/color]
    <dictproxy object at 0x008F8E30>[color=blue][color=green][color=darkred]
    >>> vars(C).keys()[/color][/color][/color]
    ['__dict__', '__module__', '__weakref__', '__doc__', 'func']

    The above shows not my_attrib
    [color=blue][color=green][color=darkred]
    >>> C.func()
    >>> vars(C).keys()[/color][/color][/color]
    ['__module__', 'my_attrib', 'func', '__dict__', '__weakref__', '__doc__']

    But after C.func() it is there
    [color=blue][color=green][color=darkred]
    >>> C.my_attrib[/color][/color][/color]
    1

    now we make an instance
    [color=blue][color=green][color=darkred]
    >>> c=C()
    >>> c.func[/color][/color][/color]
    <bound method C.func of <__main__.C object at 0x00904070>>

    looks like an ordinary bound method (though defined with "caller_of_func " in place of "self").
    [color=blue][color=green][color=darkred]
    >>> c.func('another value')
    >>> c.my_attrib[/color][/color][/color]
    'another value'[color=blue][color=green][color=darkred]
    >>> C.my_attrib[/color][/color][/color]
    1

    The instance attribute shadows the class attribute, so we can uncover the latter
    by deleting the former:
    [color=blue][color=green][color=darkred]
    >>> del c.my_attrib
    >>> c.my_attrib[/color][/color][/color]
    1

    That's really C.my_attrib found through standard attribute search.

    To get more info, read about descriptors.

    Regards,
    Bengt Richter

    Comment

    • popov

      #3
      Re: In a function, how to get the caller object ?

      Thanks Bengt for your answer, it's really what I needed !

      Regards,

      Popov

      Comment

      Working...