问题
I am running an interactive python session which builds big python data-structures (5+ GB) which take a long time to load, and so I want to exploit Python on-the-fly code change abilities at its maximum (though sometimes, without having to plan too much for that).
My current problem is the following: I have an old instance of a class that I have later modified the code and reloaded the module -- I would like the old instance to be able to use the new function definitions. How do I do that without just manually copying all the information from the old instance to a new fresh instance?
Here is what I have tried. Suppose I have the module M.py
:
class A():
def f(self):
print "old class"
Here is an interactive session:
import M
old_a = M.a()
# [suppose now I change the definition of M.A.f in the source file]
reload(M)
# I attempt to use the new class definition with the old instance:
M.A.f(old_a)
at which point I get the following type error from Python:
TypeError: unbound method f() must be called with A instance as first argument (got A instance instead)
Python is obviously not happy to receive an old instance of A even though they are basically functionally equivalent types (in my code) -- is there any way I could 'type cast' it to the new instance type so that Python wouldn't complain? Something morally like: M.A.f( (M.A) old_a )
?
回答1:
There is no casting in Python but you can change the class of an existing object: It is perfectly legal and does the job:
old_a.__class__=M.A
old_a.f()
As long as you haven't changed the relation between class methods and instance variables, changed what __init__
does or something like that this is perfectly fine.
EDIT: As jsbueno
points out: The __init__
or __new__
methods are not called at the point of changing __class__
. Further, the new __del__
will be called at destruction.
回答2:
Since you cannot cast, you need to revise your code so that these mysterious "on-the-fly code changes" can work.
Step 1. Separate Algorithm from Data. Write a very simple (and very unlikely to change) class for the raw Data. Often a list of named tuples is all you'll ever need for this.
Step 2. Create algorithms which work on the data objects by "wrapping" them instead of "updating" them.
Like this.
def some_complex_algo( list_of_named_tuples ):
for item in list_of_named_tuples:
# some calculation
yield NewTuple( result1, result2, ..., item )
Now you can attempt your processing:
result = list( some_complex_algo( source_data ) )
If you don't like the result, you only need to redefine your some_complex_algo
and rerun it. The source_data
is untouched. Indeed, it can be immutable.
来源:https://stackoverflow.com/questions/9165756/object-type-casting-in-python-after-reloading-a-module-for-on-the-fly-code-cha