[Tutor] class instance with identity crisis
Yigal Duppen
yduppen at xs4all.nl
Wed Jan 12 12:31:37 CET 2005
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
More information about the Tutor
mailing list