3

assuming the simple case where Foo is

class Foo:
    def some_func(self):
        print('hellow world')

I only have access to the variable func where func is :

func = Foo.some_func

I am trying to get the Foo class name from the variable func

func
Out[6]: <function __main__.Foo.some_func>
func.__class__.__name__
Out[7]: 'function'

I am expecting to get Foo is there anyway to do that?

Brown Bear
  • 19,655
  • 10
  • 58
  • 76
Steven G
  • 16,244
  • 8
  • 53
  • 77

1 Answers1

5

Python 3 solution:

def get_class_name(func):
    return func.__qualname__.split('.')[0]

__qualname__ method actually prints Foo.some_func for func.

Splitting the string by . and taking the first element, it should do the job.

Python 2 & 3 solution:

def get_class_name(func):
    return func.__str__().split('.')[0].split()[-1]

Edit:

In Python 3, func.__str__() prints <function Foo.some_func at 0x10c456b70>.

In Python 2, func.__str__() prints <unbound method Foo.some_func>.

Alex Fung
  • 1,996
  • 13
  • 21
  • 1
    Thanks, exactly what I am looking for. did not know about `__qualname__` – Steven G Jul 25 '18 at 12:17
  • Me either. I was using ipython and looking up dunder methods that might be useful. I guess I learnt something today! – Alex Fung Jul 25 '18 at 12:18
  • @StevenG may I ask what you are doing with this? Just interested in the use case of this. – Alex Fung Jul 25 '18 at 12:21
  • 1
    I am using this in a decorator, the decorator is used in multiple classes which represents tasks. when the task.run() has been called, I get the task name ( the class name) and send a log to SQL – Steven G Jul 25 '18 at 12:24
  • @StevenG Got it! Glad I can help with that! – Alex Fung Jul 25 '18 at 12:27
  • I removed my comment prior to the last edit because I thought you got it covered with a precedent edit. NB, the first solution works for python >= 3.3. – T.Nel Jul 25 '18 at 12:33
  • 1
    `object.__str__(func)` works even when `func.__str__` is overridden. – Solomon Ucko Jul 25 '18 at 15:16