2

I have a very strange problem.

I need to return a class object to call a function that is supposed to return the class object that called it. I know, I know. Just think of it as a contrived exercise, though for me it is a very real need.

def baz():
    # return the object instance that calls me. 

class Foo():
    def bar(self, func):
        return func()  # should return the Foo object but how???

new_foo = Foo()
new_foo_instance = new_foo.bar(baz)

is it possible to write anything in baz() that will return the object that called it?

EDIT:

to answer the comments:

I have tried to use inspect, but with no success, I even looked at the entire stack but I cannot find an entry that matches the new_foo object:

new_foo looks like this when I printed it out: <__main__.Foo object at 0x0000029AAFC4C780>

when I printed out the entire stack that entry was not found within it:

def baz():
    print(inspect.stack())
    return inspect.stack() #[1][3]

>>> [FrameInfo(frame=<frame object at 0x0000029AADB49648>, filename='return_caller.py', lineno=5, function='baz', code_context=['    print(inspect.stack())\n'], index=0), FrameInfo(frame=<frame object at 0x0000029AAD8F0DE8>, filename='return_caller.py', lineno=11, function='bar', code_context=['        return func()  # should return the Foo object but how???\n'], index=0), FrameInfo(frame=<frame object at 0x0000029AAD8AC588>, filename='return_caller.py', lineno=19, function='<module>', code_context=['new_foo_instance = new_foo.bar(baz)\n'], index=0)]

So I am not trying to get it to return a new instance of Foo, but actually the exact same instance as new_foo.

5
  • Have a look at stackoverflow.com/questions/900392/… if it helps. Let me know in comment if you face any issue. Commented Nov 10, 2018 at 7:37
  • When you call new_foo.bar(baz) what do you expect to return. Is it new Foo instance? Commented Nov 10, 2018 at 7:42
  • @AbdulNiyasPM @hygull same instance as new_foo I've edited the question for clearification Commented Nov 10, 2018 at 7:50
  • 1
    @Legit Stack If that is the case can't you call the function(baz in this case) with self?(ie, return func(self) Commented Nov 10, 2018 at 7:52
  • @AbdulNiyasPM oh, yes, I think that modification to bar would work Commented Nov 10, 2018 at 7:56

2 Answers 2

4

Use inspect:

import inspect

def baz():
    frame_infos = inspect.stack()  # A list of FrameInfo.
    frame = frame_infos[1].frame   # The frame of the caller.
    locs = frame.f_locals          # The caller's locals dict.
    return locs['self']

class Foo():
    def bar(self, func):
        return func()

f1 = Foo()
f2 = f1.bar(baz)
print(f1)
print(f2)
print(f2 is f1)  # True

Or cheat:

def baz():
    return getattr(baz, 'self', None)

class Foo():
    def bar(self, func):
        func.self = self  # Functions can be a place to store global information.
        return func()
Sign up to request clarification or add additional context in comments.

Comments

1

The above answer is perfect and this is another way to fulfill your need.

import sys 
import inspect

def baz():
    """
    Return the object instance whose method calls me
    """
    for item in dir(sys.modules[__name__]):
        elem = eval(item)

        if inspect.isclass(elem):
            foo_instance = elem()
            break

    return foo_instance

class Foo():
    """
    Foo class
    """
    def bar(self, func):
        return func()  # should return the Foo object but how???

# Instantiation and calling
new_foo = Foo()
new_foo_instance = new_foo.bar(baz)

print(new_foo_instance)       # <__main__.Foo object at 0x0000015C5A2F59E8>
print(type(new_foo_instance)) # <class '__main__.Fo


# E:\Users\Rishikesh\Projects\Python3\try>python Get_caller_object_final.py
# <__main__.Foo object at 0x0000015C5A2F59E8>
# <class '__main__.Foo'>
References »

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.