Finding what methods a Python object has
-
09-06-2019 - |
Question
Given a Python object of any kind, is there an easy way to get the list of all methods that this object has?
Or,
if this is not possible, is there at least an easy way to check if it has a particular method other than simply checking if an error occurs when the method is called?
Solution
It appears you can use this code, replacing 'object' with the object you're interested in:
object_methods = [method_name for method_name in dir(object)
if callable(getattr(object, method_name))]
I discovered it at this site. Hopefully, that should provide some further detail!
OTHER TIPS
You can use the built in dir()
function to get a list of all the attributes a module has. Try this at the command line to see how it works.
>>> import moduleName
>>> dir(moduleName)
Also, you can use the hasattr(module_name, "attr_name")
function to find out if a module has a specific attribute.
See the Guide to Python introspection for more information.
The simplest method is to use dir(objectname)
. It will display all the methods available for that object. Cool trick.
To check if it has a particular method:
hasattr(object,"method")
I believe that what you want is something like this:
a list of attributes from an object
In my humble opinion, the built-in function dir()
can do this job for you. Taken from help(dir)
output on your Python Shell:
dir(...)
dir([object]) -> list of strings
If called without an argument, return the names in the current scope.
Else, return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it.
If the object supplies a method named
__dir__
, it will be used; otherwise the default dir() logic is used and returns:
- for a module object: the module's attributes.
- for a class object: its attributes, and recursively the attributes of its bases.
- for any other object: its attributes, its class's attributes, and recursively the attributes of its class's base classes.
For example:
$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a = "I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
'translate', 'upper', 'zfill']
As I was checking your issue, I decided to demonstrate my train of thought, with a better formatting of the output of dir()
.
dir_attributes.py (Python 2.7.6)
#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output. """
__author__ = "ivanleoncz"
obj = "I am a string."
count = 0
print "\nObject Data: %s" % obj
print "Object Type: %s\n" % type(obj)
for method in dir(obj):
# the comma at the end of the print, makes it printing
# in the same line, 4 times (count)
print "| {0: <20}".format(method),
count += 1
if count == 4:
count = 0
print
dir_attributes.py (Python 3.4.3)
#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output. """
__author__ = "ivanleoncz"
obj = "I am a string."
count = 0
print("\nObject Data: ", obj)
print("Object Type: ", type(obj),"\n")
for method in dir(obj):
# the end=" " at the end of the print statement,
# makes it printing in the same line, 4 times (count)
print("| {:20}".format(method), end=" ")
count += 1
if count == 4:
count = 0
print("")
Hope that I have contributed :).
If you specifically want methods, you should use inspect.ismethod.
For method names:
import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]
For the methods themselves:
import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]
Sometimes inspect.isroutine
can be useful too (for built-ins, C extensions, Cython without the "binding" compiler directive).
Open bash shell (ctrl+alt+T on Ubuntu). Start python3 shell in it. Create object to observe methods of. Just add a dot after it and press twice "tab" and you'll see something like that:
user@note:~$ python3
Python 3.4.3 (default, Nov 17 2016, 01:08:31)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import readline
>>> readline.parse_and_bind("tab: complete")
>>> s = "Any object. Now it's a string"
>>> s. # here tab should be pressed twice
s.__add__( s.__rmod__( s.istitle(
s.__class__( s.__rmul__( s.isupper(
s.__contains__( s.__setattr__( s.join(
s.__delattr__( s.__sizeof__( s.ljust(
s.__dir__( s.__str__( s.lower(
s.__doc__ s.__subclasshook__( s.lstrip(
s.__eq__( s.capitalize( s.maketrans(
s.__format__( s.casefold( s.partition(
s.__ge__( s.center( s.replace(
s.__getattribute__( s.count( s.rfind(
s.__getitem__( s.encode( s.rindex(
s.__getnewargs__( s.endswith( s.rjust(
s.__gt__( s.expandtabs( s.rpartition(
s.__hash__( s.find( s.rsplit(
s.__init__( s.format( s.rstrip(
s.__iter__( s.format_map( s.split(
s.__le__( s.index( s.splitlines(
s.__len__( s.isalnum( s.startswith(
s.__lt__( s.isalpha( s.strip(
s.__mod__( s.isdecimal( s.swapcase(
s.__mul__( s.isdigit( s.title(
s.__ne__( s.isidentifier( s.translate(
s.__new__( s.islower( s.upper(
s.__reduce__( s.isnumeric( s.zfill(
s.__reduce_ex__( s.isprintable(
s.__repr__( s.isspace(
The problem with all methods indicated here is that you CAN'T be sure that a method doesn't exist.
In Python you can intercept the dot calling thru __getattr__
and __getattribute__
, making it possible to create method "at runtime"
Exemple:
class MoreMethod(object):
def some_method(self, x):
return x
def __getattr__(self, *args):
return lambda x: x*2
If you execute it, you can call method non existing in the object dictionary...
>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10
And it's why you use the Easier to ask for forgiveness than permission paradigms in Python.
The simplest way to get list of methods of any object is to use help()
command.
%help(object)
It will list out all the available/important methods associated with that object.
For example:
help(str)
One can create a getAttrs
function that will return an object's callable property names
def getAttrs(object):
return filter(lambda m: callable(getattr(object, m)), dir(object))
print getAttrs('Foo bar'.split(' '))
That'd return
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
'__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
'__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',
'__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']
There is no reliable way to list all object's methods. dir(object)
is usually useful, but in some cases it may not list all methods. According to dir()
documentation: "With an argument, attempt to return a list of valid attributes for that object."
Checking that method exists can be done by callable(getattr(object, method))
as already mentioned there.
...is there at least an easy way to check if it has a particular method other than simply checking if an error occurs when the method is called
While "Easier to ask for forgiveness than permission" is certainly the Pythonic way, what you are looking for maybe:
d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
d.get('foo')
# OUT: 'bar'
Take a list as an object
obj = []
list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))
You get:
['__add__',
'__class__',
'__contains__',
'__delattr__',
'__delitem__',
'__dir__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__getitem__',
'__gt__',
'__iadd__',
'__imul__',
'__init__',
'__init_subclass__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mul__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__reversed__',
'__rmul__',
'__setattr__',
'__setitem__',
'__sizeof__',
'__str__',
'__subclasshook__',
'append',
'clear',
'copy',
'count',
'extend',
'index',
'insert',
'pop',
'remove',
'reverse',
'sort']
In order to search for a specific method in a whole module
for method in dir(module) :
if "keyword_of_methode" in method :
print(method, end="\n")