When and how to do this
Changing the type ("casting") makes sense if you want to add functionality to an object created by some code you cannot change.
Assume some statement obj = some_call_to_a_library()
gives you an object of class A
. You want it to have additional functionality, say, mymethod()
.
Then you could introduce a subclass MyA
like this (Python 3 style):
class MyA(A):
@classmethod
def cast(cls, some_a: A):
"""Cast an A into a MyA."""
assert isinstance(some_a, A)
some_a.__class__ = cls # now mymethod() is available
assert isinstance(some_a, MyA)
return some_a
def mymethod(self):
...
and then write obj = MyA.cast(some_call_to_a_library())
.
If MyA
relies on additional attributes, cast
(which is a factory method) should create them.
I just did something like this when I needed a version of requests.Response
that could persist and retrieve responses to/from a file.