In a function, how to get the caller object ?

Bengt Richter bokr at oz.net
Wed Dec 3 19:43:22 EST 2003


On 3 Dec 2003 06:56:06 -0800, google at evpopov.com (popov) wrote:

>Look at this code:
>
>class C:
>    def func():
>        <caller_of_func>.my_attrib = 1
>    func = staticmethod(func)        
>
>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.

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)

 >>> class SpecialMethod(object):
 ...     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
 ...
 >>> class C(object):
 ...     def func(caller_of_func, value=1):
 ...         caller_of_func.my_attrib = value
 ...     func = SpecialMethod(func)
 ...
 >>> C
 <class '__main__.C'>
 >>> C.func
 <bound method C.func of <class '__main__.C'>>
 >>> vars(C)
 <dictproxy object at 0x008F8E30>
 >>> vars(C).keys()
 ['__dict__', '__module__', '__weakref__', '__doc__', 'func']

The above shows not my_attrib

 >>> C.func()
 >>> vars(C).keys()
 ['__module__', 'my_attrib', 'func', '__dict__', '__weakref__', '__doc__']

But after C.func() it is there

 >>> C.my_attrib
 1

now we make an instance

 >>> c=C()
 >>> c.func
 <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").

 >>> c.func('another value')
 >>> c.my_attrib
 'another value'
 >>> C.my_attrib
 1

The instance attribute shadows the class attribute, so we can uncover the latter
by deleting the former:

 >>> del c.my_attrib
 >>> c.my_attrib
 1

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

To get more info, read about descriptors.

Regards,
Bengt Richter




More information about the Python-list mailing list