Reload Tricks

Discussion in 'Python' started by Kamilche, Jan 22, 2005.

  1. Kamilche

    Kamilche Guest

    I want my program to be able to reload its code dynamically. I have a
    large hierarchy of objects in memory. The inheritance hierarchy of
    these objects are scattered over several files.

    I find that after reloading the appropriate files, and overwriting the
    __class__ of object instances, one more thing is necessary: reloading
    the __bases__ of each reloaded class. If I don't do this, the modules
    reloaded first point to old versions of the classes from later modules,
    and when the later module is reloaded, it doesn't update the
    inheritance hierarchy of classes already loaded.

    This appears to be working... but now I'm wondering, what else did it
    not change? Can I expect more toes to be blown off?

    --Kamilche
     
    Kamilche, Jan 22, 2005
    #1
    1. Advertisements

  2. Kamilche wrote:
    > I want my program to be able to reload its code dynamically. I have a
    > large hierarchy of objects in memory. The inheritance hierarchy of
    > these objects are scattered over several files.
    >
    > I find that after reloading the appropriate files, and overwriting the
    > __class__ of object instances, one more thing is necessary: reloading
    > the __bases__ of each reloaded class. If I don't do this, the modules
    > reloaded first point to old versions of the classes from later modules,
    > and when the later module is reloaded, it doesn't update the
    > inheritance hierarchy of classes already loaded.
    >
    > This appears to be working... but now I'm wondering, what else did it
    > not change? Can I expect more toes to be blown off?
    >
    > --Kamilche
    >


    There are some cases when re-assigning __class__ isn't possible, for example:
    >>> class A(object):

    ... pass
    ...
    >>> class B(dict):

    ... pass
    ...
    >>> class C:

    ... pass
    ...
    >>> a = A()
    >>> a.__class__ = B

    Traceback (most recent call last):
    File "<input>", line 1, in ?
    TypeError: __class__ assignment: 'A' object layout differs from 'B'
    >>> a.__class__ = C

    Traceback (most recent call last):
    File "<input>", line 1, in ?
    TypeError: __class__ must be set to new-style class, not 'classobj' object
    >>>


    An alternative approach (with some pros and cons) is to modify the class in
    place, using something like:

    >>> def reclass(cls, to_cls):

    ... """Updates attributes of cls to match those of to_cls"""
    ...
    ... DONOTCOPY = ("__name__","__bases__","__base__",
    ... "__dict__", "__doc__","__weakref__")
    ...
    ... fromdict = cls.__dict__
    ... todict = to_cls.__dict__
    ...
    ... # Delete any attribute present in the new class
    ... [delattr(cls,attr) for attr in fromdict.keys()
    ... if not((attr in todict) or (attr in DONOTCOPY)) ]
    ...
    ... for to_attr, to_obj in todict.iteritems():
    ...
    ... if to_attr in DONOTCOPY:
    ... continue
    ...
    ... # This overwrites all functions, even if they haven't changed.
    ... if type(to_obj) is types.MethodType:
    ... func = to_obj.im_func
    ... to_obj = types.MethodType(func,None, cls)
    ...
    ... setattr(cls, to_attr,to_obj)
    ...
    >>> class A(object):

    ... attr = "A"
    ...
    >>> class B(object):

    ... attr = "B"
    ...
    >>> a = A()
    >>> reclass(A,B)
    >>> a.attr

    'B'
    >>>


    This copies attributes of old and new-style classes (in fact anything with a
    __dict__ so probably a module would work too)

    You still run into problems trying to re-assigning __bases__ to incompatible
    objects, but this one-attribute-at-a-time approach gives you the potential to
    intercept problem cases. In the example above, problems are avoided by not
    copying __bases__.

    An additional advantage of this aprpoach is that you don't need to keep track of
    class instances, in order to change their __class__. Instances automatically
    acquire the new behavior

    One wart is that class docstrings are not writeable, so cannot be copied. Why?

    Michael
     
    Michael Spencer, Jan 22, 2005
    #2
    1. Advertisements

  3. Kamilche

    Kamilche Guest

    That's a powerful advantage - not having to track class instances.
    Thanks for the tip! I just got done doing it 'my way' though, now I'll
    have to change it. It took me all day! :-D
     
    Kamilche, Jan 22, 2005
    #3
  4. Kamilche

    Kamilche Guest

    Would it be possible to just not copy any attribute that starts and
    ends with '__'? Or are there some important attributes being copied?
     
    Kamilche, Jan 22, 2005
    #4
  5. Kamilche <> wrote:

    > I want my program to be able to reload its code dynamically. I have a
    > large hierarchy of objects in memory. The inheritance hierarchy of
    > these objects are scattered over several files.


    Michael Hudson has a nice custom metaclass for that in Activestate's
    online cookbook -- I made some enhancements to it as I edited it for the
    forthcoming 2nd edition of the cookbook (due out in a couple of months),
    but the key ideas are in the online version too (sorry, no URL at hand).


    Alex
     
    Alex Martelli, Jan 22, 2005
    #5
  6. Kamilche wrote:
    > I want my program to be able to reload its code dynamically. I have a
    > large hierarchy of objects in memory. The inheritance hierarchy of
    > these objects are scattered over several files.
    >

    Michael Spencer wrote:
    > An alternative approach (with some pros and cons) is to modify the class in place, using something like:
    >
    > >>> def reclass(cls, to_cls):

    > ... """Updates attributes of cls to match those of to_cls"""
    > ...
    > ... DONOTCOPY = ("__name__","__bases__","__base__",
    > ... "__dict__", "__doc__","__weakref__")

    etc...

    Kamilche wrote:
    > Would it be possible to just not copy any attribute that starts and
    > ends with '__'? Or are there some important attributes being copied?



    Possible? of course, it's Python ;-)

    But there are many 'magic' attributes for behavior that you probably do want to
    copy:

    e.g., __getitem__, __setitem__ etc...

    See: http://docs.python.org/ref/specialnames.html

    Michael Hudson's recipe:
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164
    does auto-reloading "automatically", at the price of changing the type of the
    classes you want to manage. It's a very convenient approach for interactive
    development (which is the recipe's stated purpose). It works by tracking
    instances and automatically updating their class. If your program relies on
    class identity, you may run into problems.


    Michael
     
    Michael Spencer, Jan 22, 2005
    #6
  7. Kamilche

    Kamilche Guest

    Well, I look forward to seeing the new version. I have the old version
    of the Python cookbook, it was very useful!
     
    Kamilche, Jan 23, 2005
    #7
  8. Kamilche <> wrote:

    > Well, I look forward to seeing the new version. I have the old version
    > of the Python cookbook, it was very useful!


    I hope the new one is even better -- many more recipes, all updated to
    Python 2.3 and 2.4. The old one will remain useful for all those who
    need to keep using older versions of Python, though; to fit more recipes
    in, the historical discussions of how you did things with Python 1.5.2,
    1.6, 2.0 etc have been ruthlessly snipped...


    Alex
     
    Alex Martelli, Jan 23, 2005
    #8
    1. Advertisements

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. Cowboy \(Gregory A. Beamer\)

    Tips and Tricks: Page Templates

    Cowboy \(Gregory A. Beamer\), Dec 3, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    465
    Colin Young
    Dec 4, 2003
  2. =?Utf-8?B?S2VubmV0aCBQ?=

    Trying localization with Sams Tips&Tricks

    =?Utf-8?B?S2VubmV0aCBQ?=, Nov 15, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    1,651
    =?Utf-8?B?S2VubmV0aCBQ?=
    Nov 15, 2004
  3. Joshua Beall
    Replies:
    26
    Views:
    227,901
    AndreiKaa
    Jun 29, 2007
  4. gen_tricomi
    Replies:
    2
    Views:
    952
    gen_tricomi
    May 23, 2006
  5. Stefan Mueller
    Replies:
    4
    Views:
    430
    Stefan Mueller
    Nov 5, 2005
Loading...

Share This Page