0

A colleague of mine demonstrated some code to me which I found quite interesting:

class A(object):
    def evolve(self):
        if self.foo > 10:
             self.__class__ = B

class B(A):
    def bar(self):
        print "I'm a B"

... that's essentially the gist of it. The idea is to "specialize" an instance at runtime after other computations have been processed. I have been thinking about it, and even while it feels wrong (especially the assignment to __class__), I can see nothing wrong with it, as long as the type hierarchy is properly taken into account.

Is there maybe a way to do this in Python without the assignment to __class__?

Again, I don't see too much wrong with this, as the assignment to __class__ effectively only changes the resolution order... no?

exhuma
  • 20,071
  • 12
  • 90
  • 123

2 Answers2

2

The classical method to do this sort of thing is the Strategy Pattern. A set of similar classes are created, and then the primary class acts as a facade, with its methods delegating operations to the contained class/object.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • I have discussed this with my colleague. The problem is that the full interface is not known in advance. The projects acts as abstraction to a proprietary interface which is humongous! It's infeasible to abstract all of it. We only need a minute subset. I'm only relaying the info. I had not have the chance to fully analyse the problem... – exhuma Dec 02 '13 at 09:04
1

What you describe here is a "technically possible" implementation of either the State or Strategy patterns. Now while this is legal python code I strongly advise against it unless except as a last resort hack for objects that are instanciated in parts of the code you dont have control over and even then there might be better ways.

From personal experience (and I did experiment a lot with Python's most dynamic features) sticking to more conventionals implementations of the State and Strategy patterns makes for a more readable, testable and maintainable code.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118