Adding bound methods dynamically...

2005-08-30 Thread Kevin Little
#!/usr/bin/env python

'''
I want to dynamically add or replace bound methods in a class.  I want
the modifications to be immediately effective across all instances,
whether created before or after the class was modified.  I need this
to work for both old ('classic') and new style classes, at both 2.3
and 2.4.  I of course want to avoid side effects, and to make the
solution as light-weight as possible.

Question for the experts: Is the solution coded in AddBoundMethod()
acceptable to the Pythonian Gods? :) It does seem to work -- tested
at 2.3.5 (RH Linux) and 2.4.1 (WinXP)

Is there a more pythonic way that's as straight forward?
'''

def AddBoundMethod( cls, name, method ):
   '''
   Dynamically add to the class 'cls' a bound method.

   Invoking this method instantly adds (or overwrites) the
   bound method identified by 'name' with the code contained in
   'method', EVEN FOR PRE-EXISTING INSTANCES OF THE CLASS. The
   'method' parameter should be a non-class function that has 'self'
   as its first parameter.
   '''

   try: types
   except NameError: import types

   #
   # this is the crux of this example, short and sweet...
   #
   exec "%s.%s = types.MethodType( method, None, %s )" \
  % ( cls.__name__, name, cls.__name__ )

#
# The remainder (50x longer than the solution!) is test code...
#

# one new-style class...
class NewStyleClass( object ):

   def __init__ ( self, objname ):
  print "Created a NewStyleClass, id %d, %s" % \
( id( self ), objname ) self.objname = objname

   def ExistingMethod( self, msg ):
  print "Original ExistingMethod, id %d, %s: '%s'" % \
( id( self ), self.objname, msg )

# one 'classic' style class...
class OldStyleClass:

   def __init__ ( self, objname ):
  print "Created a OldStyleClass, id %d, %s" % \
( id( self ),  objname ) self.objname = objname

   def ExistingMethod( self, msg ):
  print "Original ExistingMethod, id %d, %s: '%s'" % \
( id( self ), self.objname, msg )

# two non-class functions that *look* like bound methods in a class;
# one returns a value, the other just outputs a string...
def NeverInOriginalClass( self, msg ):
   return "Never in original class, id %d, %s: '%s'" % \
  ( id( self ), self.objname, msg )

def NewExistingMethod( self, msg ):
   print  "REPLACED ExistingMethod, id %d, %s: '%s'" % \
  ( id( self ), self.objname, msg )

# a test routine...
def Test( cls ):

   print "--- %s --" % \
 cls.__name__

   print "type of class %s is '%s'" % ( cls.__name__, type( cls ) )

   before_change = cls('instance created before change')

   print "type of object before_change is '%s'" % type(before_change)

   # 'A' shows that we start with an existing method
   before_change.ExistingMethod( 'A' )

   print "*** Replacing bound method 'ExistingMethod'..."

   AddBoundMethod( cls, "ExistingMethod", NewExistingMethod )

   after_change = cls( 'instance created AFTER  change' )

   print "type of after_change is '%s'" % type( after_change )

   # 'B' and 'C' show we've replaced an existing method, both on
   # pre-existing instances and instances created after using
   # AddBoundMethod()
   before_change.ExistingMethod( 'B' )
   after_change.ExistingMethod( 'C' )

   print "*** Adding new bound method 'AddedMethod'..."

   AddBoundMethod( after_change.__class__, "AddedMethod",
   NeverInOriginalClass )

   # 'D' and 'E' show we've added a brand new method, both on
   # pre-existing instances and instances created after using
   # AddBoundMethod()
   print "%s" % before_change.AddedMethod( 'D' )
   print "%s" % after_change.AddedMethod( 'E' )


if __name__ == '__main__':

   Test( OldStyleClass )
   Test( NewStyleClass )

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Adding bound methods dynamically... CORRECTED

2005-08-30 Thread Kevin Little
#!/usr/bin/env python

# Sorry... :} cut/paste error fixed...

'''
I want to dynamically add or replace bound methods in a class.  I want
the modifications to be immediately effective across all instances,
whether created before or after the class was modified.  I need this
to work for both old ('classic') and new style classes, at both 2.3
and 2.4.  I of course want to avoid side effects, and to make the
solution as light-weight as possible.

Question for the experts: Is the solution coded in AddBoundMethod()
acceptable to the Pythonian Gods? :) It does seem to work -- tested
at 2.3.5 (RH Linux) and 2.4.1 (WinXP)

Is there a more pythonic way that's as straight forward?
'''

def AddBoundMethod( cls, name, method ):
   '''
   Dynamically add to the class 'cls' a bound method.

   Invoking this method instantly adds (or overwrites) the
   bound method identified by 'name' with the code contained in
   'method', EVEN FOR PRE-EXISTING INSTANCES OF THE CLASS. The
   'method' parameter should be a non-class function that has 'self'
   as its first parameter.
   '''

   try: types
   except NameError: import types

   #
   # this is the crux of this example, short and sweet...
   #
   exec "%s.%s = types.MethodType( method, None, %s )" \
  % ( cls.__name__, name, cls.__name__ )

#
# The remainder (50x longer than the solution!) is test code...
#

# one new-style class...
class NewStyleClass( object ):

   def __init__ ( self, objname ):
  print "Created a NewStyleClass, id %d, %s" % \
( id( self ), objname )
  self.objname = objname

   def ExistingMethod( self, msg ):
  print "Original ExistingMethod, id %d, %s: '%s'" % \
( id( self ), self.objname, msg )

# one 'classic' style class...
class OldStyleClass:

   def __init__ ( self, objname ):
  print "Created a OldStyleClass, id %d, %s" % \
( id( self ),  objname )
  self.objname = objname

   def ExistingMethod( self, msg ):
  print "Original ExistingMethod, id %d, %s: '%s'" % \
( id( self ), self.objname, msg )

# two non-class functions that *look* like bound methods in a class;
# one returns a value, the other just outputs a string...
def NeverInOriginalClass( self, msg ):
   return "Never in original class, id %d, %s: '%s'" % \
  ( id( self ), self.objname, msg )

def NewExistingMethod( self, msg ):
   print  "REPLACED ExistingMethod, id %d, %s: '%s'" % \
  ( id( self ), self.objname, msg )

# a test routine...
def Test( cls ):

   print "--- %s --" % \
 cls.__name__

   print "type of class %s is '%s'" % ( cls.__name__, type( cls ) )

   before_change = cls('instance created before change')

   print "type of object before_change is '%s'" % type(before_change)

   # 'A' shows that we start with an existing method
   before_change.ExistingMethod( 'A' )

   print "*** Replacing bound method 'ExistingMethod'..."

   AddBoundMethod( cls, "ExistingMethod", NewExistingMethod )

   after_change = cls( 'instance created AFTER  change' )

   print "type of after_change is '%s'" % type( after_change )

   # 'B' and 'C' show we've replaced an existing method, both on
   # pre-existing instances and instances created after using
   # AddBoundMethod()
   before_change.ExistingMethod( 'B' )
   after_change.ExistingMethod( 'C' )

   print "*** Adding new bound method 'AddedMethod'..."

   AddBoundMethod( after_change.__class__, "AddedMethod",
   NeverInOriginalClass )

   # 'D' and 'E' show we've added a brand new method, both on
   # pre-existing instances and instances created after using
   # AddBoundMethod()
   print "%s" % before_change.AddedMethod( 'D' )
   print "%s" % after_change.AddedMethod( 'E' )


if __name__ == '__main__':

   Test( OldStyleClass )
   Test( NewStyleClass )

-- 
http://mail.python.org/mailman/listinfo/python-list


Hooking any/all 'calls'

2006-12-27 Thread Kevin Little
In Python 2.4 or 2.5, what is the easiest way to hook any and all
callables such that designated code is executed at the very start and
end of each call? (Yes, I'm trying to come up with a little debugging
tool!:) Is there a single metaclass who's "__call__" method can be
wrapped to do this?

TIA,
   -k
 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Hooking any/all 'calls'

2006-12-28 Thread Kevin Little
Thanks, Robert! That was exactly what I was looking for.
 -k

"fumanchu" <[EMAIL PROTECTED]> wrote:
>Kevin Little wrote:
>> In Python 2.4 or 2.5, what is the easiest way to hook any and all
>> callables such that designated code is executed at the very start and
>> end of each call? (Yes, I'm trying to come up with a little debugging
>> tool!:) Is there a single metaclass who's "__call__" method can be
>> wrapped to do this?
>
>You probably want sys.settrace, which is specifically designed for
>creating debuggers, and is the basis for pdb, the debugger in the
>standard library. See
>http://docs.python.org/lib/module-sys.html#l2h-5159
>
>Feel free also to look through my own debugging aid (for clues on how
>to implement your own, or just to use for your needs):
>http://projects.amor.org/misc/wiki/PyConquer
>
>
>Robert Brewer
>System Architect
>Amor Ministries
>[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list