Making a Fast Copy of an Object
Credit: Alex Martelli
Problem
You
need to implement the special method _ _copy_ _ so your class can cooperate with the
copy.copy function. If the _ _init_ _ method of your class is slow, you need to bypass it and
get an empty object of the class.
Solution
Here’s a solution that works for both new-style and classic classes:
def empty_copy(obj):
class Empty(obj._ _class_ _):
def _ _init_ _(self): pass
newcopy = Empty( )
newcopy._ _class_ _ = obj._ _class_ _
return newcopyYour classes can use this function to implement _ _copy_ _ as follows:
class YourClass:
def _ _init_ _(self):
print "assume there's a lot of work here"
def _ _copy_ _(self):
newcopy = empty_copy(self)
print "now copy some relevant subset of self's attributes to newcopy"
return newcopyHere’s a usage example:
if _ _name_ _ == '_ _main_ _':
import copy
y = YourClass( ) # This, of course, does run _ _init_ _
print y
z = copy.copy(y) # ...but this doesn't
print zDiscussion
Python doesn’t implicitly copy your objects when you
assign them. This is a great thing, because it gives fast, flexible,
and uniform semantics. When you need a copy, you explicitly ask for
it, ideally with the
copy.copy
function, which knows how to copy built-in types, has reasonable
defaults for your own objects, and lets you customize the copying
process by defining a special method _ _copy_ _ in
your own classes. If you want instances of a class to be noncopyable,
you can define _ _copy_ _ and raise a
TypeError there. In ...