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

Reply via email to