Dynamically Update Class Definitions?

Discussion in 'Python' started by chrisspen@gmail.com, Nov 11, 2005.

  1. Guest

    Is there a way to loop through all instantiated objects and update
    their classes when a source file changes? I know about Michael Hudson's
    method
    (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164), but
    you have to modify all your classes to subclass AutoReloader. Is there
    something less intrusive (visitor pattern?) that you can use like
    update(old_class, new_class) to automagically do the work?

    Chris
     
    , Nov 11, 2005
    #1
    1. Advertising

  2. <> wrote:

    > Is there a way to loop through all instantiated objects and update
    > their classes when a source file changes? I know about Michael Hudson's
    > method
    > (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164), but
    > you have to modify all your classes to subclass AutoReloader. Is there
    > something less intrusive (visitor pattern?) that you can use like
    > update(old_class, new_class) to automagically do the work?


    If you're in no hurry, you COULD loop over all of gc.get_objects(),
    identify all those which are instances of old_class and "somehow" change
    their classes to new_class -- of course, x.__class__ = new_class may
    well not be sufficient, in which case you'll have to pass to update a
    callable to do the instance-per-instance job.


    Alex
     
    Alex Martelli, Nov 12, 2005
    #2
    1. Advertising

  3. Alex Martelli wrote:
    > <> wrote:
    >
    >
    >>Is there a way to loop through all instantiated objects and update
    >>their classes when a source file changes? I know about Michael Hudson's
    >>method
    >>(http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/160164), but
    >>you have to modify all your classes to subclass AutoReloader. Is there
    >>something less intrusive (visitor pattern?) that you can use like
    >>update(old_class, new_class) to automagically do the work?

    >
    >
    > If you're in no hurry, you COULD loop over all of gc.get_objects(),
    > identify all those which are instances of old_class and "somehow" change
    > their classes to new_class -- of course, x.__class__ = new_class may
    > well not be sufficient, in which case you'll have to pass to update a
    > callable to do the instance-per-instance job.


    Couldn't I just loop over gc.get_referrers(cls), checking for instances
    of the class object? Since class instances refer to their class, the gc
    seems to be doing the exact same thing as Hudson's fancy metaclass. Or
    am I missing something?

    Chris
     
    Chris Spencer, Nov 12, 2005
    #3
  4. Chris Spencer wrote:
    > Alex Martelli wrote:


    >> If you're in no hurry, you COULD loop over all of gc.get_objects(),
    >> identify all those which are instances of old_class and "somehow" change
    >> their classes to new_class -- of course, x.__class__ = new_class may
    >> well not be sufficient, in which case you'll have to pass to update a
    >> callable to do the instance-per-instance job.

    >
    >
    > Couldn't I just loop over gc.get_referrers(cls), checking for instances
    > of the class object? Since class instances refer to their class, the gc
    > seems to be doing the exact same thing as Hudson's fancy metaclass. Or
    > am I missing something?
    >
    > Chris


    In fact, the following code seems to work, and doesn't require any
    modification to new-style class based code:

    import os
    import time
    import threading
    import inspect
    import gc
    import copy

    class ModuleUpdater(object):
    '''
    This will constantly check a module's source file for updates, reload
    if any are detected, and update all class instances.
    Only works for new-style classes.

    Use like:
    checker = ModuleUpdater(module=mymod)
    checker.start()
    '''
    def __init__(self, module):
    self.module = module
    self.lastloaded = time.time()
    self.running = 0
    self.t = None
    def __call__(self):
    self.running = 1
    while self.running:
    self.check()
    time.sleep(1)
    def check(self):
    lastmodified = os.stat(inspect.getsourcefile(self.module))[8]
    if lastmodified > self.lastloaded:
    print 'update detected for',self.module.__name__
    oldmod = copy.copy(self.module.__dict__)
    newmod = reload(self.module)
    try:
    for name,obj in oldmod.items():
    if isinstance(obj,type) and name in newmod.__dict__:
    newobj = newmod.__dict__[name]
    referrers = gc.get_referrers(obj)
    for referrer in referrers:
    if isinstance(referrer,obj):
    # update old class instances to use new
    class
    referrer.__class__ = newobj
    print 'update loaded for',self.module.__name__
    except Exception, e:
    print 'unable to load update for %s: %s' %
    (self.module.__name__, str(e))
    self.lastloaded = lastmodified
    return 1
    return 0
    def start(self):
    t = threading.Thread(target=self)
    t.setDaemon(1)
    t.start()
    self.t = t
    return t
    def stop(self, blocking=0):
    self.running = 0
    if blocking:
    self.t.join()

    if __name__ == '__main__':

    import testmod # any module containing class Bar with method meth
    uc = ModuleUpdater(testmod)

    uc.start()

    b=testmod.Bar(1)
    while 1: # meanwhile, modify the source to testmod.py
    time.sleep(1)
    print b.meth()
     
    Chris Spencer, Nov 12, 2005
    #4
    1. Advertising

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. E11
    Replies:
    1
    Views:
    4,788
    Thomas Weidenfeller
    Oct 12, 2005
  2. John Ericson
    Replies:
    0
    Views:
    428
    John Ericson
    Jul 19, 2003
  3. Jason_SanDiego2006

    Dynamically changing style definitions in page header

    Jason_SanDiego2006, Mar 6, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    505
    Eliyahu Goldin
    Mar 6, 2007
  4. _robby
    Replies:
    1
    Views:
    415
    Matt Nordhoff
    Mar 14, 2008
  5. Rainer Weikusat
    Replies:
    1
    Views:
    216
    Rainer Weikusat
    Mar 8, 2013
Loading...

Share This Page