Wednesday, July 6, 2011

How to use reflection

A simple code snippet that use reflection to print names of attributes, methods and doc strings:
class Obj:
 """ An object that use reflection """

 def __init__(self,name):
  """ the constructor of this object """
  self.name = name

 def print_methods(self):
  """ print all the methods of this object and their doc string"""
  print '\n* Methods *'
  for names in dir(self):
   attr = getattr(self,names)
   if callable(attr):
    print names,':',attr.__doc__

 def print_attributes(self):
  """ print all the attributes of this object and their value """
  print '* Attributes *'
  for names in dir(self):
   attr = getattr(self,names)
   if not callable(attr):
    print names,':',attr

 def print_all(self):
  """ calls all the methods of this object """
  for names in dir(self):
   attr = getattr(self,names)
   if callable(attr) and names != 'print_all' and names != '__init__':
    attr() # calling the method

o = Obj('the my object')
o.print_all()
Which gives the following output:
* Attributes *
__doc__ :  An object that use reflection 
__module__ : __main__
name : the my object

* Methods *
__init__ :  the constructor of this object 
print_all :  calls all the methods of this object 
print_my_attributes :  print all the attributes of this object 
print_my_methods :  print all the methods of this object 

7 comments:

  1. I've just started learning Python about a month ago, however, I've noticed if you type in 'class Obj (object):' on line 1, you get an error. I've learned that creating a class with no '(object)' is an old-style class... so my question is why would there be an error if one was to create a new-style class (with '(object)' type after)?

    Btw, the error I got was "__init__() takes exactly 2 arguments (1 given)"

    ReplyDelete
  2. which version of Python are you using?

    ReplyDelete
    Replies
    1. Python 2.7, I do believe.

      Delete
  3. I just compiled it with the same version and works fine. Try to copy the entire snippet and to compiler without any change.

    ReplyDelete
  4. Any way to get the parameters?

    ReplyDelete
  5. @JustGlowing: I suppose you don't get Anonymous's question

    He/ She has modified your code with the below in the first line of your code

    class Obj:

    has been changed to

    class Obj(object):

    and when this is done in your code it fails with the above mentioned error :)
    and that is true... with the new-style class/ object there are more functions inherited, other than the one's in your class.
    so it throws error when the reflection part of the code calls them.

    ReplyDelete
  6. Here is a workaround if you are using python3.3, as you'll most likely come to an error...

    In the print_all method, change the if validation to:

    if names[:2] != "__" and names[-2:] != "__" and names != "print_all" and callable(attr):

    ReplyDelete