Dynamically Generate Methods

Discussion in 'Python' started by GZ, Nov 18, 2011.

  1. GZ

    GZ Guest

    Hi,

    I have a class Record and a list key_attrs that specifies the names of
    all attributes that correspond to a primary key.

    I can write a function like this to get the primary key:

    def get_key(instance_of_record):
    return tuple(instance_of_record.__dict__[k] for k in key_attrs)

    However, since key_attrs are determined at the beginning of the
    program while get_key() will be called over and over again, I am
    wondering if there is a way to dynamically generate a get_ley method
    with the key attributes expanded to avoid the list comprehension/
    generator.

    For example, if key_attrs=['A','B'], I want the generated function to
    be equivalent to the following:

    def get_key(instance_of_record):
    return (instance_of_record['A'],instance_of_record['B'] )

    I realize I can use eval or exec to do this. But is there any other
    way to do this?

    Thanks,
    gz
    GZ, Nov 18, 2011
    #1
    1. Advertising

  2. GZ wrote:
    > Hi,
    >
    > I have a class Record and a list key_attrs that specifies the names of
    > all attributes that correspond to a primary key.
    >
    > I can write a function like this to get the primary key:
    >
    > def get_key(instance_of_record):
    > return tuple(instance_of_record.__dict__[k] for k in key_attrs)
    >
    > However, since key_attrs are determined at the beginning of the
    > program while get_key() will be called over and over again, I am
    > wondering if there is a way to dynamically generate a get_ley method
    > with the key attributes expanded to avoid the list comprehension/
    > generator.
    >
    > For example, if key_attrs=['A','B'], I want the generated function to
    > be equivalent to the following:
    >
    > def get_key(instance_of_record):
    > return (instance_of_record['A'],instance_of_record['B'] )
    >
    > I realize I can use eval or exec to do this. But is there any other
    > way to do this?
    >
    > Thanks,
    > gz
    >
    >
    >
    >

    Hi,

    you may want to do something like

    class Record(object):
    PRIMARY_KEY = []
    def __init__(self):
    for key in self.PRIMARY_KEY:
    setattr(self, key, None)

    def getPrimaryKeyValues(self):
    return [ getattr(self, key) for key in self.PRIMARY_KEY]


    class FruitRecord(Record):
    PRIMARY_KEY = ['fruit_id', 'fruit_name']



    JM

    PS : there's a high chance that a python module already exists to access
    your database with python objects.
    Jean-Michel Pichavant, Nov 18, 2011
    #2
    1. Advertising

  3. GZ

    Ian Kelly Guest

    On Fri, Nov 18, 2011 at 7:51 AM, GZ <> wrote:
    > Hi,
    >
    > I have a class Record and a list key_attrs that specifies the names of
    > all attributes that correspond to a primary key.
    >
    > I can write a function like this to get the primary key:
    >
    > def get_key(instance_of_record):
    > return tuple(instance_of_record.__dict__[k] for k in key_attrs)
    >
    > However, since key_attrs are determined at the beginning of the
    > program while get_key() will be called over and over again, I am
    > wondering if there is a way to dynamically generate a get_ley method
    > with the key attributes expanded to avoid the list comprehension/
    > generator.


    (Accidentally sent this to the OP only)

    This is exactly what the attrgetter factory function produces.

    from operator import attrgetter
    get_key = attrgetter(*key_attrs)

    But if your attribute names are variable and arbitrary, I strongly
    recommend you store them in a dict instead. Setting them as instance
    attributes risks that they might conflict with the regular attributes
    and methods on your objects.

    Cheers,
    Ian
    Ian Kelly, Nov 18, 2011
    #3
  4. GZ

    GZ Guest

    Hi All,

    I see. It works.

    Thanks,
    GZ

    On Nov 18, 12:04 pm, Ian Kelly <> wrote:
    > On Fri, Nov 18, 2011 at 7:51 AM, GZ <> wrote:
    > > Hi,

    >
    > > I have a class Record and a list key_attrs that specifies the names of
    > > all attributes that correspond to a primary key.

    >
    > > I can write a function like this to get the primary key:

    >
    > > def get_key(instance_of_record):
    > >   return tuple(instance_of_record.__dict__[k] for k in key_attrs)

    >
    > > However, since key_attrs are determined at the beginning of the
    > > program while get_key() will be called over and over again, I am
    > > wondering if there is a way to dynamically generate a get_ley method
    > > with the key attributes expanded to avoid the list comprehension/
    > > generator.

    >
    > (Accidentally sent this to the OP only)
    >
    > This is exactly what the attrgetter factory function produces.
    >
    > from operator import attrgetter
    > get_key = attrgetter(*key_attrs)
    >
    > But if your attribute names are variable and arbitrary, I strongly
    > recommend you store them in a dict instead.  Setting them as instance
    > attributes risks that they might conflict with the regular attributes
    > and methods on your objects.
    >
    > Cheers,
    > Ian
    >
    >
    GZ, Nov 20, 2011
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Weng Tianxiang
    Replies:
    5
    Views:
    1,300
    Christophe
    Feb 16, 2006
  2. Replies:
    3
    Views:
    397
    red floyd
    Apr 7, 2006
  3. Steven Samuel Cole
    Replies:
    0
    Views:
    200
    Steven Samuel Cole
    Aug 25, 2008
  4. Harlan Messinger
    Replies:
    2
    Views:
    2,280
    John Bell
    Mar 28, 2010
  5. Kenneth McDonald
    Replies:
    5
    Views:
    299
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page