adding methods on the fly (was Re: Smalltalk and Python)
Alex Martelli
aleaxit at yahoo.com
Mon Dec 18 04:12:42 EST 2000
More information about the Python-list mailing list
Mon Dec 18 04:12:42 EST 2000
- Previous message (by thread): Smalltalk and Python
- Next message (by thread): Smalltalk and Python
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
[Note: we've already been kindly asked to stop posting this thread to fj.comp.lang.ruby, using comp.lang.ruby instead, so I edited the newsgroups line accordingly] "Greg Ewing" <greg at cosc.canterbury.ac.nz> wrote in message news:3A3D8815.801E773D at cosc.canterbury.ac.nz... > Andrew Dalke wrote: > > > > >>> bed = make_a(Furniture, Surface, Scenery) > > But how do I give it methods? Most easily, actually -- in any of several handy ways. > bed(Furniture, Surface, Scenery): > > def lie_on(self): > print "It's so comfy, you fall instantly" \ > " asleep, and dream of a golden key sitting" \ > " on a shelf in the pantry." Using my version of make_a, i.e., to recap: import new def make_a(*classes, **attribs): return new.classobj('blob', classes, attribs)() class Furniture: def comfy(self): return 1 class Surface: def genus(self): return 0 # Imagine a spherical cow... class Scenery: def description(self): return "boring" bed = make_a(Furniture, Surface, Scenery) you have a range of choices, e.g., the most explicit: def anewmethodjustforbed(self): print "elegant and comfy" bed.lie_on = new.instancemethod(anewmethodjustforbed, bed, bed.__class__) or, a tad less explicitly but perhaps more simply: bed.__class__.lie_on = anewmethodjustforbed which takes advantage of the implicit function->method coercion [which happens when a reference to a function is bound to a *class*'s attribute -- not an _instance_ attribute], and of course of the fact that instance 'bed' is the sole instance of its class, so, in order to affect that instance's behavior, we're at liberty to tweak its class's:-). It's just an issue of preferred style. If one is using the new module to build the class for object 'bed', I think it might be more consistent to keep using the same module also for building new methods to assign on the fly; if one is using Andrew's original suggestion and building that class less explicitly, then the implicit coercion based approach might be better. Note that my version of function make_a takes keyword arguments and turns them into class-attributes for the new class, so, if you already know what methods you want to add to 'bed' as you generate it, another alternative is to take advantage of that: bed = make_a(Furniture, Surface, Scenery, lie_on=anewmethodjustforbed) Of course you'll want to factor things appropriately. If you have many methods that just print out stuff while ignoring self, or using self just for read access to instance data attributes, etc, you might build a function encapsulating that: def printout(self, message): print message % self.__dict__ and use it to build all on-the-fly methods of this kind: bed = make_a(Furniture, Surface, Scenery, lie_on=lambda self: printout(self, "whatever")) or you might prefer a closure-factory approach, rather than the lambda approach: def printout_maker(message): def printout(self, message=message): print message % self.__dict__ return printout bed = make_a(Furniture, Surface, Scenery, lie_on=printout_maker("whatever")) or, of course, the closure-factory could also use module new rather than the implicit approach I've taken here (which strictly parallel's Andrew's original suggestion for make_a, except that here we're using a local function rather than a local class as in his case). I think that some one out of these approaches, or some variant thereof, will probably meet all kinds of "how do I add a method" requirements. Alex
- Previous message (by thread): Smalltalk and Python
- Next message (by thread): Smalltalk and Python
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list