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 - [email protected]
http://mail.python.org/mailman/listinfo/tutor