Exec inside a class method to call other class methods?

J. Clifford Dyer jcd at sdf.lonestar.org
Fri Dec 26 01:16:41 CET 2008

On Thu, 25 Dec 2008 13:22:15 -0500
Matthew Dubins <matt.dubins at sympatico.ca> wrote:

> Hello all,
> I have made a python script to upload contact information from an
> excel worksheet to an online database.  One part of the program that
> really tripped me up was when I wanted to call specific class methods
> that I had made to deal with specific types of contact information
> (Parent's name, Child's name, Phone #, etc).  My first thought was to
> make it easy using the exec statement. 
> The code (a method within a class) looked like this:
> ----------
> def parse(self, data, data_type)
>     exec "self.__parse_%s(data)" % data_type
> ----------
> The data_type variable contains strings that exactly match the
> spellings of the 2nd word in the titles of the class methods that I
> wanted to call for each data_type inputted into the parse function.
> For some reason, *it didn't work*.  Alternately, I found the ugly
> code shown below to be functional.  As you can see, for each
> data_type, I call the corresponding class method that I've
> specified.  Please help me to transform my ugly functional code into
> concise functional code. :)
> Thanks,
> Matthew
> ----------
>     def parse(self, data, data_type):
>         if data_type == 'nocall':
>             self.__parse_nocall(data)
>         elif data_type == 'DOB':
>             self.__parse_DOB(data)
>         elif data_type == 'gender':
>             self.__parse_gender(data)
>         elif data_type == 'Prematurity':
>             self.__parse_Prematurity(data)
>         elif data_type == 'email':
>             self.__parse_email(data)
>         elif data_type == 'languages':
>             self.__parse_languages(data)
>         elif data_type == 'phone':
>             self.__parse_phone(data)
>         elif data_type == 'cname':
>             self.__parse_cname(data)
>         elif data_type == 'pname':
>             self.__parse_pname(data)
>         elif data_type == 'address':
>             self.__parse_address(data)
>         elif data_type == 'duedate':
>             self.__parse_dudedate(data)

This is precisely what subclasses were designed for:

class DataField(object):
    def __init__(self, data):
        self.data = data
    def parse(self):

class AddressDataField(DataField):
    def parse(self):
        self.data = do_something(self.data)

class DueDateDataField(DataField):
    def parse(self):
        self.data = parse_date(self.data)

and so forth.  Then your if/else chain can be pulled out to the place where you instantiate each field: 

if data_type=='address':
elif data_type=='due_date':
    field = DataField(data)

Then a simple field.parse() will do the right thing to field.data().  You might even include the parsing in __init__().  Define __init__() once on the base class (DataField), and it will pull the proper parse method from the subclass.

Happy Hacking, and Merry Christmas.

More information about the Python-list mailing list