0

When I'm prototyping a new project on Jupyter, I sometimes find that I want to add/delete methods to an instance. For example:

class A(object):
   def __init__(self):
       # some time-consuming function

   def keep_this_fxn(self):
       return 'hi'

a = A()

## but now I want to make A -> A_new

class A_new(object):
   def __init__(self, v):
       # some time-consuming function
       self._new_prop = v

   def keep_this_fxn(self):
       return 'hi'

   @property
   def new_prop(self):
       return self._new_prop

   def new_fxn(self):
       return 'hey'

Without having to manually do A.new_fxn = A_new.new_fxn or reinitializing the instance, is it possible to have this change done automatically? Something like

def update_instance(a, A_new)
    # what's here?

a = update_instance(a, A_new(5)) ## should not be as slow as original initialization!

>>> type(a) ## keeps the name, preferably!
<A>
>>> a.keep_this_fxn() ## same as the original
'hi'
>>> a.new_fxn(). ## but with new functions
'hey'
>>> a.new_prop ## and new properties
5

Related posts don't seem to cover this, especially new properties and new args: How to update instance of class after class method addition? Monkey patching class and instance in Python

Here's my current attempt:

def update_class_instance(instance, NewClass, new_method_list):
    OrigClass = type(instance).__mro__[0]
    
    for method in new_method_list:
        setattr(OrigClass, method, getattr(NewClass, method))    

but (a) I still have to specify new_method_list (which I prefer to be handled automatically if possible, and (b) I have no idea what to do about the new properties and args.

irene
  • 2,085
  • 1
  • 22
  • 36
  • "Without having to manually do `A.new_fxn = A_new.new_fxn`…is it possible to have this change done automatically?" It's not clear what you mean by "automatically" here. Assigning the function to the class seems pretty simple. Do you want to avoid changing the original class? – Mark Feb 20 '23 at 05:31
  • Basically what I want is to update the cell containing the definition of the class `A`, run a function named `update_instance(a, A_new)`, and then have `a` get updated with all the properties and methods of the updated `A` (or `A_new`). This can be handy if the revisions are extensive. – irene Feb 20 '23 at 05:33
  • @Mark please see the update for my current attempt – irene Feb 20 '23 at 05:35
  • Hmm, interesting. Would `a.__class__ = type('A', (A_new, A), {'_new_prop': 5})` do what you need? – Mark Feb 20 '23 at 05:44
  • Hi @Mark, that may, but what if `new_prop` also has a setter function? Would that take care of it too? – irene Feb 20 '23 at 05:55
  • I think this would work as expected with a setter. – Mark Feb 20 '23 at 05:58
  • Hi @Mark, `a.new_prop` doesn't work, only `a._new_prop` does – irene Feb 20 '23 at 06:10
  • Are you talking about the setter? If so, did you define a `@new_prop.setter` on `A_new`? – Mark Feb 20 '23 at 06:12

0 Answers0