Terry Reedy wrote: > Steven D'Aprano wrote: >> On Sat, 16 May 2009 09:55:39 -0700, Emanuele D'Arrigo wrote: >> >>> Hi everybody, >>> >>> let's assume I have a module with loads of classes inheriting from one >>> class, from the same module, i.e.: >> [...] >>> Now, let's also assume that myFile.py cannot be changed or it's >>> impractical to do so. Is there a way to replace the SuperClass at >>> runtime, so that when I instantiate one of the subclasses NewSuperClass >>> is used instead of the original SuperClass provided by the first module >>> module? >> >> That's called "monkey patching" or "duck punching". >> >> http://en.wikipedia.org/wiki/Monkey_patch >> >> http://wiki.zope.org/zope2/MonkeyPatch >> >> http://everything2.com/title/monkey%2520patch > > If the names of superclasses is resolved when classes are instantiated, > the patching is easy. If, as I would suspect, the names are resolved > when the classes are created, before the module becomes available to the > importing code, then much more careful and extensive patching would be > required, if it is even possible. (Objects in tuples cannot be > replaced, and some attributes are not writable.)
It may be sufficient to patch the subclasses: $ cat my_file.py class Super(object): def __str__(self): return "old" class Sub(Super): def __str__(self): return "Sub(%s)" % super(Sub, self).__str__() class Other(object): pass class SubSub(Sub, Other): def __str__(self): return "SubSub(%s)" % super(SubSub, self).__str__() if __name__ == "__main__": print Sub() $ cat main2.py import my_file OldSuper = my_file.Super class NewSuper(OldSuper): def __str__(self): return "new" + super(NewSuper, self).__str__() my_file.Super = NewSuper for n, v in vars(my_file).iteritems(): if v is not NewSuper: try: bases = v.__bases__ except AttributeError: pass else: if OldSuper in bases: print "patching", n v.__bases__ = tuple(NewSuper if b is OldSuper else b for b in bases) print my_file.Sub() print my_file.SubSub() $ python main2.py patching Sub Sub(newold) SubSub(Sub(newold)) Peter -- http://mail.python.org/mailman/listinfo/python-list