How do I get list of methods in a Python class?
Asked Answered
F
450

An example (listing the methods of the optparse.OptionParser class):

>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
 ('add_option', <unbound method OptionParser.add_option>),
 ('add_option_group', <unbound method OptionParser.add_option_group>),
 ('add_options', <unbound method OptionParser.add_options>),
 ('check_values', <unbound method OptionParser.check_values>),
 ('destroy', <unbound method OptionParser.destroy>),
 ('disable_interspersed_args',
  <unbound method OptionParser.disable_interspersed_args>),
 ('enable_interspersed_args',
  <unbound method OptionParser.enable_interspersed_args>),
 ('error', <unbound method OptionParser.error>),
 ('exit', <unbound method OptionParser.exit>),
 ('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
 ...
 ]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...

Notice that getmembers returns a list of 2-tuples. The first item is the name of the member, the second item is the value.

You can also pass an instance to getmembers:

>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...
Filippa answered 15/12, 2009 at 23:41 Comment(10)
perfect, the predicate part is key, otherwise you get the same thing as dict with the extra meta info. Thanks.Theobald
Will this produce a list of all methods in the class (including ones that are inherited from other classes), or will it only list the methods that are explicitly defined in that class?Seventieth
It includes inherited methods.Filippa
This only gives me the base class's methods, not the classes of the derived's.. - Update: this is because all methods in derived were static.Gaol
getmembers will only return class attributes defined in the metaclass when the argument is a class.Ellary
inspect.isroutine might be a more appropriate predicate; inspect.ismethod doesn't work for all objects' methods.Cranberry
An interactive console will display the return value of inspect.getmembers(). If you want to display the result from inside a script, you will need to do print(inspect.getmembers(...)).Filippa
If OptionParser inherits some other class then those methods will also get listedFelid
on python 3.7 at least this doesn't work, you have to instantiate the classDismember
In Python 3 there is no such thing as an unbound method. In 3.7, this works with the class: inspect.getmembers(OptionsParser, predicate=inspect.isfunction)Filippa
E
295

There is the dir(theobject) method to list all the fields and methods of your object (as a tuple) and the inspect module (as codeape write) to list the fields and methods with their doc (in """).

Because everything (even fields) might be called in Python, I'm not sure there is a built-in function to list only methods. You might want to try if the object you get through dir is callable or not.

Eldaelden answered 15/12, 2009 at 23:49 Comment(0)
A
222

Python 3.x answer without external libraries

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]

dunder-excluded result:

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]
Acidhead answered 21/8, 2016 at 7:33 Comment(2)
Cool, but it does not include getter-setter methods decorated with @property and @property.setterKaleighkalends
this what worked with objects.Doak
T
65

Say you want to know all methods associated with list class Just Type The following

 print (dir(list))

Above will give you all methods of list class

Transfusion answered 4/12, 2018 at 8:28 Comment(1)
print([ m for m in dir(my_class) if not m.startswith('__')])Misadvise
M
39

Try the property __dict__.

Moonstruck answered 15/12, 2009 at 23:42 Comment(3)
I think you mean dict. But that lists the attributes of the instance, not the methods.Ripe
…that didn't work for me either. Having consulted the Markdown syntax, I think I mean __dict__.Ripe
@Ripe you're probably doing "self.__dict__" or, more generically, calling the instance version of __dict__. However classes have a __dict__ too and that should display the class methods :)Leastwise
L
33

you can also import the FunctionType from types and test it with the class.__dict__:

from types import FunctionType

class Foo:
    def bar(self): pass
    def baz(self): pass

def methods(cls):
    return [x for x, y in cls.__dict__.items() if type(y) == FunctionType]

methods(Foo)  # ['bar', 'baz']
Leastwise answered 29/3, 2015 at 18:58 Comment(5)
This worked well for me. I did add and not x.startswith('_') to the end of the list comprehension for my use to ignore __init__'s and private methods.Conah
You can get rid of the import of FunctionType by using a throwaway lambda with type(): type(lambda:0)Downs
isinstance would be the better than type(y) == FunctionType here.Headless
for callable function you can just replace x in the start to y (use [y for x, y in cls.__dict__.items() if type(y) == FunctionType])Eventuate
this doesn't work with objects, only classes, otherwise __dict__.items() won't have any moethodsOdisodium
T
29

You can list all methods in a python class by using the following code

dir(className)

This will return a list of all the names of the methods in the class

Teague answered 22/5, 2020 at 14:25 Comment(1)
This also reports non-method class attributes.Caveat
F
15

Note that you need to consider whether you want methods from base classes which are inherited (but not overridden) included in the result. The dir() and inspect.getmembers() operations do include base class methods, but use of the __dict__ attribute does not.

Faceharden answered 20/9, 2011 at 0:21 Comment(0)
J
10

If your method is a "regular" method and not a staticmethod, classmethod etc.
There is a little hack I came up with -

for k, v in your_class.__dict__.items():
    if "function" in str(v):
        print(k)

This can be extended to other type of methods by changing "function" in the if condition correspondingly.
Tested in Python 2.7 and Python 3.5.

Jephthah answered 4/5, 2018 at 16:30 Comment(3)
Not sure why this was downvoted... it did actually solve the problem I was having.Swiger
if isinstance(v, types.FunctionTypes) would be cleaner. You can also extend this to check for attributes of type classmethod and staticmethod.Caveat
Typo in what chepner recommended. Use if isinstance(v, types.FunctionType)Stripy
S
10

Try print(help(ClassName)) It prints out methods of the class

Symposiac answered 5/1, 2021 at 0:45 Comment(1)
Amazing! I learnt something new. Unfortunately this does not list the staticmethods of a class: I wonder if that's even possible.Frostbite
F
8

I just keep this there, because top rated answers are not clear.

This is simple test with not usual class based on Enum.

# -*- coding: utf-8 -*-
import sys, inspect
from enum import Enum

class my_enum(Enum):
    """Enum base class my_enum"""
    M_ONE = -1
    ZERO = 0
    ONE = 1
    TWO = 2
    THREE = 3

    def is_natural(self):
            return (self.value > 0)
    def is_negative(self):
            return (self.value < 0)

def is_clean_name(name):
    return not name.startswith('_') and not name.endswith('_')
def clean_names(lst):
    return [ n for n in lst if is_clean_name(n) ]
def get_items(cls,lst):
    try:
            res = [ getattr(cls,n) for n in lst ]
    except Exception as e:
            res = (Exception, type(e), e)
            pass
    return res


print( sys.version )

dir_res = clean_names( dir(my_enum) )
inspect_res = clean_names( [ x[0] for x in inspect.getmembers(my_enum) ] )
dict_res = clean_names( my_enum.__dict__.keys() )

print( '## names ##' )
print( dir_res )
print( inspect_res )
print( dict_res )

print( '## items ##' )
print( get_items(my_enum,dir_res) )
print( get_items(my_enum,inspect_res) )
print( get_items(my_enum,dict_res) )

And this is output results.

3.7.7 (default, Mar 10 2020, 13:18:53) 
[GCC 9.2.1 20200306]
## names ##
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO']
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO', 'name', 'value']
['is_natural', 'is_negative', 'M_ONE', 'ZERO', 'ONE', 'TWO', 'THREE']
## items ##
[<my_enum.M_ONE: -1>, <my_enum.ONE: 1>, <my_enum.THREE: 3>, <my_enum.TWO: 2>, <my_enum.ZERO: 0>]
(<class 'Exception'>, <class 'AttributeError'>, AttributeError('name'))
[<function my_enum.is_natural at 0xb78a1fa4>, <function my_enum.is_negative at 0xb78ae854>, <my_enum.M_ONE: -1>, <my_enum.ZERO: 0>, <my_enum.ONE: 1>, <my_enum.TWO: 2>, <my_enum.THREE: 3>]

So what we have:

  • dir provide not complete data
  • inspect.getmembers provide not complete data and provide internal keys that are not accessible with getattr()
  • __dict__.keys() provide complete and reliable result

Why are votes so erroneous? And where i'm wrong? And where wrong other people which answers have so low votes?

Foreshorten answered 28/4, 2020 at 22:3 Comment(0)
L
7

This also works:

In mymodule.py:

def foo(x):
   return 'foo'
def bar():
   return 'bar'

In another file:

import inspect
import mymodule
method_list = [ func[0] for func in inspect.getmembers(mymodule, predicate=inspect.isroutine) if callable(getattr(mymodule, func[0])) ]

Output:

['foo', 'bar']

From the Python docs:

inspect.isroutine(object)

Return true if the object is a user-defined or built-in function or method.

Lore answered 23/1, 2019 at 11:19 Comment(0)
D
6

There's this approach:

[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]

When dealing with a class instance, perhaps it'd be better to return a list with the method references instead of just names¹. If that's your goal, as well as

  1. Using no import
  2. Excluding private methods (e.g. __init__) from the list

It may be of use. You might also want to assure it's callable(getattr(obj, m)), since dir returns all attributes within obj, not just methods.

In a nutshell, for a class like

class Ghost:
    def boo(self, who):
        return f'Who you gonna call? {who}'

We could check instance retrieval with

>>> g = Ghost()
>>> methods = [getattr(g, m) for m in dir(g) if not m.startswith('__')]
>>> print(methods)
[<bound method Ghost.boo of <__main__.Ghost object at ...>>]

So you can call it right away:

>>> for method in methods:
...     print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS

¹ An use case:

I used this for unit testing. Had a class where all methods performed variations of the same process - which led to lengthy tests, each only a tweak away from the others. DRY was a far away dream.

Thought I should have a single test for all methods, so I made the above iteration.

Although I realized I should instead refactor the code itself to be DRY-compliant anyway... this may still serve a random nitpicky soul in the future.

Datcha answered 14/4, 2020 at 3:33 Comment(0)
D
3
def find_defining_class(obj, meth_name):
    for ty in type(obj).mro():
        if meth_name in ty.__dict__:
            return ty

So

print find_defining_class(car, 'speedometer') 

Think Python page 210

Dona answered 12/7, 2014 at 16:41 Comment(3)
Indentation of 5? Capitalizing keywords? Non-pep8-style spacing?Skilful
Not once the coding convention nazis got to it!Oligosaccharide
How does this answer the question?Lubbock
I
3
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]

gives an identical list as

methods = inspect.getmembers(o, predicate=inspect.ismethod)

does.

Inge answered 22/7, 2019 at 16:8 Comment(1)
There's a subtle distinction this will overlook (though perhaps not one you would care about, depending on the use case): this will count callable instance attributes as methods. Methods are class attributes.Caveat
D
3

You can use a function which I have created.

def method_finder(classname):

    non_magic_class = []

    class_methods = dir(classname)

    for m in class_methods:

        if m.startswith('__'):

            continue

        else:

            non_magic_class.append(m)

    return non_magic_class




method_finder(list)

Output:

['append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']
Desrochers answered 12/10, 2020 at 9:23 Comment(0)
C
1

I know this is an old post, but just wrote this function and will leave it here is case someone stumbles looking for an answer:

def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True):

    def acceptMethod(tup):
        #internal function that analyzes the tuples returned by getmembers tup[1] is the 
        #actual member object
        is_method = inspect.ismethod(tup[1])
        if is_method:
            bound_to = tup[1].im_self
            internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__'
            if internal and exclude_internal:
                include = False
            else:
                include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only)
        else:
            include = False
        return include
    #uses filter to return results according to internal function and arguments
    return filter(acceptMethod,inspect.getmembers(the_class))
Correggio answered 17/7, 2014 at 5:57 Comment(1)
This code does not do what it is intended as published. Giving class_only or instance_only will result in empty list.Operant
U
1

use inspect.ismethod and dir and getattr

 import inspect
 class ClassWithMethods:
    
    def method1(self):
        print('method1')
    def method2(self):
        print('method2')

obj=ClassWithMethods()

method_names = [attr for attr in dir(obj) if inspect.ismethod(getattr(obj,attr))

print(method_names)

output:

[[('method1', <bound method ClassWithMethods.method1 of <__main__.ClassWithMethods object at 0x00000266779AF388>>), ('method2', <bound method ClassWithMethods.method2 of <__main__.ClassWithMethods object at 0x00000266779AF388>>)]]
Unburden answered 16/8, 2021 at 14:37 Comment(0)
S
0

None of the above worked for me.

I've encountered this problem while writing pytests.

The only work-around I found was to:

1- create another directory and place all my .py files there

2- create a separate directory for my pytests and then importing the classes I'm interested in

This allowed me to get up-to-dated methods within the class - you can change the method names and then use print(dir(class)) to confirm it.

Selfrealization answered 29/7, 2021 at 12:10 Comment(0)
O
0

For my use case, I needed to distinguish between class methods, static methods, properties, and instance methods. The inspect module confuses the issue a bit (particularly with class methods and instance methods), so I used vars based on a comment on this SO question. The basic gist is to use vars to get the __dict__ attribute of the class, then filter based on various isinstance checks. For instance methods, I check that it is callable and not a class method. One caveat: this approach of using vars (or __dict__ for that matter) won't work with __slots__. Using Python 3.6.9 (because it's what the Docker image I'm using as my interpreter has):

class MethodAnalyzer:

    class_under_test = None

    @classmethod
    def get_static_methods(cls):
        if cls.class_under_test:
            return {
                k for k, v in vars(cls.class_under_test).items()
                if isinstance(v, staticmethod)
            }
        return {}

    @classmethod
    def get_class_methods(cls):
        if cls.class_under_test:
            return {
                k for k, v in vars(cls.class_under_test).items()
                if isinstance(v, classmethod)
            }
        return {}

    @classmethod
    def get_instance_methods(cls):
        if cls.class_under_test:
            return {
                k for k, v in vars(cls.class_under_test).items()
                if callable(v) and not isinstance(v, classmethod)
            }
        return {}

    @classmethod
    def get_properties(cls):
        if cls.class_under_test:
            return {
                k for k, v in vars(cls.class_under_test).items()
                if isinstance(v, property)
            }
        return {}

To see it in action, I created this little test class:

class Foo:

    @staticmethod
    def bar(baz):
        print(baz)

    @property
    def bleep(self):
        return 'bloop'

    @classmethod
    def bork(cls):
        return cls.__name__

    def flank(self):
        return 'on your six'

then did:

MethodAnalyzer.class_under_test = Foo
print(MethodAnalyzer.get_instance_methods())
print(MethodAnalyzer.get_class_methods())
print(MethodAnalyzer.get_static_methods())
print(MethodAnalyzer.get_properties())

which output

{'flank'}
{'bork'}
{'bar'}
{'bleep'}

In this example I'm discarding the actual methods, but if you needed to keep them you could just use a dict comprehension instead of a set comprehension:

{
    k, v for k, v in vars(cls.class_under_test).items()
    if callable(v) and not isinstance(v, classmethod)
}
Oleograph answered 4/11, 2022 at 10:28 Comment(0)
B
-1

This is just an observation. "encode" seems to be a method for string objects

str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'

However, if str1 is inspected for methods, an empty list is returned

inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []

So, maybe I am wrong, but the issue seems to be not simple.

Berk answered 7/1, 2020 at 15:52 Comment(1)
'a' is an object, whose type is str. You can see this by running type('a'). inspect.getmember() takes a type parameter, so you need to call inspect.getmember(str) to see what you expect.Dialecticism
S
-1

To produce a list of methods put the name of the method in a list without the usual parenthesis. Remove the name and attach the parenthesis and that calls the method.

    def methodA():
        print("@ MethodA")

    def methodB():
        print("@ methodB")

    a = []
    a.append(methodA)
    a.append(methodB)
    for item in a:
        item()
Synod answered 7/8, 2020 at 16:18 Comment(0)
T
-1

Just like this

pprint.pprint([x for x in dir(list) if not x.startswith("_")])
Tatianna answered 10/4, 2022 at 12:4 Comment(1)
That will also list attributesBuilder
B
-2
class CPerson:
    def __init__(self, age):
        self._age = age

    def run(self):
        pass

    @property
    def age(self): return self._age

    @staticmethod
    def my_static_method(): print("Life is short, you need Python")

    @classmethod
    def say(cls, msg): return msg


test_class = CPerson
# print(dir(test_class))  # list all the fields and methods of your object
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ == 'function' and not name.startswith('__')])
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ != 'function' and not name.startswith('__')])

output

[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]
Bradbury answered 8/3, 2019 at 3:56 Comment(0)
H
-6

If you want to list only methods of a python class

import numpy as np
print(np.random.__all__)
Herniorrhaphy answered 25/3, 2019 at 6:46 Comment(3)
That's a module, not a class.Lubbock
@Lubbock It is applied for every class, all is exist in every classHerniorrhaphy
No, it doesn't. It doesn't even exist in all modules.Lubbock

© 2022 - 2024 — McMap. All rights reserved.