Pallab Pain
Pallab Pain

Reputation: 134

How to get a function's name from a object passed as that function's parameter in Python?

Let's say, I have a function named my_function and I'm passing an object as its parameter in the following way:

my_obj = MyClass()

my_function(my_obj)

Is there a way using which I can print the name of the function inside a method of MyClass?

Let's say that MyClass has a method called display_info inside it and it prints the name of the function in where the object of MyClass is passed.

An example would be:

class MyClass:

    def print_log(self):
        # some code


    def random_method_1():
        pass

    def random_method_2():


def my_function(param1, some_name, some_number):
    # some code

# Instantiating MyClass
my_object = MyClass()

# Calling my_function
my_function(my_object, "John Doe", 38478347)

my_object.print_log()
# Above line of code should be able to print "my_function"

Upvotes: 3

Views: 118

Answers (1)

bakkal
bakkal

Reputation: 55448

Design your program better

If you need this systematically you might want a better designed program, e.g. one that injects the name of the parent or calling entity into e.g. my_obj.display_info(caller='something')

class MyClass:
    def display_info(self, caller):
        print caller

def my_function(my_obj):
    my_obj.display_info(caller='my_function')

The above allows that param to be injected by each caller.

Or keep a reference to the caller in MyClass.caller at init time if possible, or set it on the spot as needed e.g.

# pseudo code
class MyClass:
   def __init__(self, caller):
        self.caller = caller

   def display_info(self):
        print self.caller

my_obj = MyClass(caller='caller')
my_obj.display_info()

my_obj.caller = 'new_caller'
my_obj.display_info()

The inspect hack to avoid

The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects.

Yes usng inspect. When you call inspect.stack() you get a record of frame objects. So we use stack()[1] to get the previous frame, which is a tuple where the third element is the name of the caller (my_function). Hence stack()[1][3].

>>> import inspect
>>> class MyClass():
...     def display_info(self):
...         print inspect.stack()[1][3]
... 
>>> def my_function(my_obj):
...     my_obj.display_info()
... 
>>> my_obj = MyClass()
>>> my_function(my_obj)
my_function   # <--- The result you wanted
>>> 
>>> def another_fn(my_obj):
...     my_obj.display_info()
... 
>>> another_fn(my_obj)
another_fn

This provides the result you want (prints the name of the calling function)

Upvotes: 3

Related Questions