[Chicago] Creating property() members programmatically

Brantley Harris deadwisdom at gmail.com
Sat Feb 7 17:57:00 CET 2009


So it's easy enough to declare properties on classes, but rather
difficult to do so on objects themselves (I'm not even sure it's
possible, well not good form anyhow.)

So you have a few options.  One is to subclass your Encoder with an
intermediate class, and then add properties, dynamically to it:
  class LameEncoder(Encoder):
    @classmethod
    def add_property(cls, attr, default):
      def setter(self, v):
        setattr(self, '_%s' % attr, v)
      def getter(self):
        return getattr(self, '_%s' % attr, default)
      setatter(cls, attr, property(gettter, setter))

  for attr, default in PARAMETER_LIST:
    LameEncoder.add_property(atter, default)

Another is to override the __setattr__ method on the intermediate
class, so that when an attribute is assigned, you can run this
function.  You have to be careful though because everything goes
through this.:
  class LameEncoder(Encoder):
    def __setattr__(self, k, v):
       if (k in PARAMATER_LIST):
          try:
             self.set_lame_parameter(k, v)
          except LameError:
             raise Something
       else:
          self.__dict__[k] = v

Or maybe this could be made easier with a Descriptor.  I'll let you
google that one.  Suffice to say it's a sort of property object, that
lets you define what to do when it's assigned to and gotten from.

Also, this assuming that the Encoder object isn't in your code, if it
is you can just dump this stuff onto it.

Hope that helps.

On Sat, Feb 7, 2009 at 9:27 AM, Tim Gebhardt <tim at gebhardtcomputing.com> wrote:
> Hello Chipy,
>
> Does anyone know of a way to create property() members on an object
> programmatically?  Anything I've Googled with "property" and
> "programmatically" doesn't really come up with what I'm looking for.
>
> Here's my use case:
>
> I'm creating a ctypes wrapper for the LAME MP3 library.  There are quite a
> few parameters that someone can set when encoding an MP3, such as the
> bitrate, number of audio channels, high pass frequency, blah, blah, blah.
> There's about 70.  The issue is that there's 3 places in my wrapper where I
> have to declare them: once in the global LAME state object, once in setting
> up the argument types and return types of the LAME getter/setter functions,
> and once in my high level Python "Encoder" object.
>
> So to make things easy and less error prone I declared a list of the
> parameters and their types so I could reuse the data I hand-typed in about
> these properties.  I also have a small dictionary of overrides for
> parameters that aren't gettable or settable or that need to be handled with
> special circumstances.  This worked fine for my first 2 places where I
> needed the data, but I'm struggling to get it to work for the 3rd part, my
> high-level Encoder object.
>
> I need to be able to create a property() on my Encoder object because
> setting a LAME parameter on an MP3 stream actually needs to call the LAME
> library, and if the return value's not good then I need to throw an
> exception.
>
> The best I've been able to do is use my data about the LAME parameters,
> output the Python code I need to a text file, and copy/paste that into my
> object's declaration.
>
> Does anyone know how I could create a bunch of property() items on an object
> based on a list of data?
>
> Thanks,
>
> -Tim Gebhardt
> tim at gebhardtcomputing.com
>
> _______________________________________________
> Chicago mailing list
> Chicago at python.org
> http://mail.python.org/mailman/listinfo/chicago
>
>


More information about the Chicago mailing list