rhall
rhall

Reputation: 75

How to get all names of a classes' classmethods in Python

I want to find out all classmethods of class Something below by using code reflection. With all classmethods i mean all methods which are decorated with @classmethod. I don't actually know if that is the same.

class Something:
    @classmethod
    def a(cls):
        print('a')

    @staticmethod
    def b(cls):
        print('b')

    def c(self):
        print('c')

So in this case I expect getting a list which contains only 'a':

get_classmethod_names(Something) == ['a']

Upvotes: 1

Views: 531

Answers (1)

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 95948

This can be as simple as iterating through the classes attributes and checking for classmethod objects:

In [1]: class Something:
   ...:     @classmethod
   ...:     def a(cls):
   ...:         print('a')
   ...:
   ...:     @staticmethod
   ...:     def b(cls):
   ...:         print('b')
   ...:
   ...:     def c(self):
   ...:         print('c')
   ...:

In [2]: [attr for attr, obj in vars(Something).items() if isinstance(obj, classmethod)]
Out[2]: ['a']

Note, if you care about inherited classmethods, then you have to check it for every class in your classe's method-resolution order, so:

In [3]: class BaseSomething:
   ...:     @classmethod
   ...:     def u(cls):
   ...:         print('u')
   ...:
   ...: class Something(BaseSomething):
   ...:     @classmethod
   ...:     def a(cls):
   ...:         print('a')
   ...:
   ...:     @staticmethod
   ...:     def b(cls):
   ...:         print('b')
   ...:
   ...:     def c(self):
   ...:         print('c')
   ...:

In [4]: Something.mro()
Out[4]: [__main__.Something, __main__.BaseSomething, object]

In [5]: [
   ...:     attr
   ...:     for cls in Something.mro()
   ...:     for attr, obj in vars(cls).items()
   ...:     if isinstance(obj, classmethod)
   ...: ]
Out[5]: ['a', 'u']

Upvotes: 3

Related Questions