3

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"
3
  • 1
    I think you should clarify what you mean. How it's to be used and what result you expect. Commented Jan 14, 2016 at 9:24
  • The answer is basically no, but I don't really understand your question. When do you intend this to be printed? Do you want my_function(my_obj) to result in "my_function" being printed? If so, why not just do that inside my_function? Commented Jan 14, 2016 at 9:25
  • 2
    I think @bakkal has a great answer for you, I would like to point out that it sounds like you are creating a "weird machine" that will have "side effects". This is quite bad practice. Maybe you have a good motivation for wanting this design, but in general, I would say your problem is architectural, not programmatical. Commented Jan 14, 2016 at 9:33

1 Answer 1

3

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)

Sign up to request clarification or add additional context in comments.

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.