Replace Whole Object Through Object Method

Bruno Desthuilliers bdesth.quelquechose at
Tue Jun 27 00:14:58 EDT 2006

digitalorganics at a écrit :
> Bruno Desthuilliers wrote:
>>digitalorganics at a écrit :
>>>Bruno Desthuilliers wrote:
>>>>Instead of exposing problems with your solution, you may want to expose
>>>>the real use case ?
>>>I'm working with a team that's doing social modeling, and for example,
>>>I need to model workers that at some point in the program may or may
>>>not also become employers.
>>If I understand correctly, only some of the existing workers will become
>>employers ?
>>>Now, I want the workers to take on all
>>>behaviors and attributes of an employer in addition to their
>>>pre-existing "worker" behaviors and attributes.
>>wrt/ behaviors, it's easy as pie. Attributes (I mean instance
>>attributes) are another problem, but I don't have enough informations to
>>deal with this problem here.
>>>Also, as I'm sure you
>>>guessed, the workers' attributes need to retain their values at that
>>>point in the program, so a brand new worker-employer object wouldn't in
>>>itself do the trick.
>>Here's a simple stupid possible solution:

> Won't work because there will be employers that aren't workers.

Then don't subclass Employer from Worker !-)

(don't mind, just kidding)

> And yes, only some workers will become employers,
> but also only some
> employers will also be workers (at some point in program). Let me be
> more clear:
> workers
> --> subset of workers --become--> employers
> employers
> --> subset of employers --become--> workers
> It is very important that both should maintain attribute values,
> regardless of whether they take on new "roles".

Seems obvious. But just a question, BTW: do workers and employers share 
the same attributes ? And if not, how do you intend to initialize the 
employers attributes on workers (and the other way round) ?

> Furthermore, this is a
> very simple case and ultimately in my program an object 

*Any* object ?-)

> should be able
> to dynamically take on a multitude of roles (classes of behavior)
 > without mucking at all with their pre-existing states.

Multiple roles at the same time, or sequentially ? And in the first case 
(which I assume), do you have the case of overriding behaviors ? And if 
yes, how should the resolution order be defined ? And what about 
attributes ? (I mean, do your 'roles' have specific attributes ?)

FWIW, just another simple (and very Q&D) snippet:

class ObjectWithRoles(object):
   def _change(self, *bases):
     self.__class__ = type(self.__class__.__name__, bases, {})

   def has_role(self, role):
     return role in self.__class__.__bases__

   def add_role(self, role):
     if not self.has_role(role):
       self._change(self.__class__, role)

   def remove_role(self, role):
     if self.has_role(role):
       self._change(*(cls for cls in self.__class__.__bases__ \
                      if cls is not role))

NB : Not tested (and not sure what it'll do) with roles subclassing 
other roles, or ObjectWithRoles as roles...

wrt/ per-role attributes, you'd of course need to pass them to 
add_role(). A convenient way of maintaining some sanity here would be to 
use descriptors for all of these attributes, and store their values in a 
per-role dict, with the role name as attribute name.

More information about the Python-list mailing list