44

If I define:

class Bar(object):

    @staticmethod
    def bar():
        # code
        pass

class Foo(Bar):
    # code
    pass

Is it possible for a function call Foo.bar() to determine the class name Foo?

Jean-Pierre Chauvel
  • 946
  • 2
  • 9
  • 21

3 Answers3

56

Replace the staticmethod with a classmethod. This will be passed the class when it is called, so you can get the class name from that.

class Bar(object):

    @classmethod
    def bar(cls):
        # code
        print cls.__name__

class Foo(Bar):
    # code
    pass

>>> Bar.bar()
Bar

>>> Foo.bar()
Foo
Dave Kirby
  • 25,806
  • 5
  • 67
  • 84
  • 16
    This does not answer the question. The question was how to do it with a static method. – sebix Nov 10 '16 at 21:57
  • What happens when this is not possible -- for example, a third party library relies on a specific signature? – gt6989b Mar 23 '18 at 15:27
  • 3
    `classmethods` are "static" methods, they have no access to an object which would require the `self` parameter, `cls` only has access to the Class and not an Object Instance. The difference is that a `classmethod` can modify the state of the Class itself @sebix – Seraf Jan 23 '19 at 18:29
3

If you need to find the class information, the appropriate way is to use @classmethod.

class Bar(object):
    @classmethod
    def bar(cls):
        # code
        print(cls.__name__)

class Foo(Bar):
    # code
    pass

Now your bar method has a reference to the class as cls which is the actual class of the caller. And as shown in the code, cls.__name__ is the name of the class you are looking for.

>>> Foo.bar()
Foo
>>> Bar.bar()
Bar
Muhammad Alkarouri
  • 23,884
  • 19
  • 66
  • 101
1

As option, if you need determine class from staticmethod (not classmethod) I guess following code could be helpful:

class Bar(object):
    @staticmethod
    def bar():
        pass


class Foo(Bar):
    pass


foo_instance = Foo()
bar_static_function = foo_instance.bar
class_name = bar_static_function.__qualname__.split(".")[0]
print(class_name)  # Foo
Yuriy Leonov
  • 536
  • 1
  • 9
  • 33