On Wednesday 12 January 2005 12:10, Kent Johnson wrote: > A couple of ideas: > > You could have dry() return the new weapon: > def dry(self): > return Prune() > > then the client code would be > weapon = weapon.dry() > > > You could have the weapon encapsulate another object and delegate to it.
As an alternative solution, you could use the Proxy pattern; this approach has the advantage that there is no dynamic reassignment of the __class__ attribute. The following program shows what I mean: class Apple: def whoami(self): print "I am an apple!" def __str__(self): return "Apple" class Egg: def whoami(self): print "I am an egg!" def __str__(self): return "Egg" class Proxy: def __init__(self): self.delegate = Apple() self.is_apple = True def __getattr__(self, attr): return getattr(self.delegate, attr) def change(self): if self.is_apple: self.delegate = Egg() else: self.delegate = Apple() self.is_apple = not self.is_apple if __name__ == "__main__": thing = Proxy() thing.whoami() print thing thing.change() thing.whoami() print thing thing.change() thing.whoami() print thing This will give the following output: I am an apple! Apple I am an egg! Egg I am an apple! Apple The magic here lies in the __getattr__ (note the double underscores) method; whenever the Proxy is asked for an attribute (such as a method), it delegates this question to the self.delegate. Alternatively, if the __getattr__ is a bit too much magic, you could also duplicate the attributes that you actually want to expost: class Proxy: def __init__(self): # as above def whoami(self): self.delegate.whoami() def __str__(self): return str(self.delegate) def change(self): # as above As others have stated, you should use this pattern with care. On the other hand, I do believe that there are instances when this can be useful, as long as the delegates have more or less the same interface (the same attributes). Yigal _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor