Implementing deepcopy

M

Mr.Rech

Hi all,
I'm writing a class with some attributes which deepcopy can't cope
with, and I need some more clarifications. Sorry for my newbie
questions, but I'm a newbie indeed (or a sort of).

Suppose one of the attributes of my class is a dictionary whose values
are callable functions, such as:
...... pass

Now if I try:

My question is: anotherdict is really a copy of adict? If so, what is
the difference between its definition and the following:

??

Thanks in advance,
Andrea.
 
A

Alex Martelli

Mr.Rech said:
Suppose one of the attributes of my class is a dictionary whose values
are callable functions, such as:

..... pass


Now if I try:

Right, because functions are not copyable (although you could, if you
wished, write a way to copy them and copy_reg it).

Right, as it's a shallow copy.

My question is: anotherdict is really a copy of adict? If so, what is
the difference between its definition and the following:

No difference whatsoever, and in fact

is yet another way to do just the same thing -- a shallow copy.

The use of copy.copy(foo) is recommended when you aren't sure what type
you're dealing with in 'foo', but want the same identical type as a
result; the use of dict(foo) is recommended when you aren't sure what
type you're dealing with in 'foo', but want a dict as a result.

If you're certain you're dealing with a dict, then, if this code is
critical for your app's performance, pick the fastest way. Use timeit
to find the fastest way, e.g., on my iBook:

Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'copy.copy(d)'
100000 loops, best of 3: 17.3 usec per loop
Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'd.copy()'
100000 loops, best of 3: 11.4 usec per loop
Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'dict(d)'
100000 loops, best of 3: 12.8 usec per loop
Helen:~ alex$

I would avoid copy.copy (measurably slower) and end up using (as I
usually do...) dict(d), but I wouldn't bitch against anybody choosing to
use d.copy() instead for a 10%-or-so gain in speed.

Personally, I find that list(L), dict(D), set(S) and so on are the best
way to perform shallow copies for known-type objects, and strongly
dislike type-specific divergences such as L[:] and D.copy() and
S.copy(), but there's no community consensus on this point.


Alex
 
M

Mr.Rech

Thanks for your answer. Since perfomances are not an issue in my case I
think I'd stay with copy.copy(). In this way I'm not required to know
in advance the object type, and I can implement a __deepcopy__ method
for my own classes as follows:
new = self.__class__.__new__(self.__class__)
memo[id(self)] = new
for key, val in self.__dict__.iteritems():
try:
setattr(new, key, copy.deepcopy(val, memo))
except TypeError:
setattr(new, key, copy.copy(val))
return new

The method is quite general (at least I hope so), and can be easily
inherited by all the subclasses without any major change. Is that
right? Am I missing something here? Any better way to implement this?

Thanks again,
Andrea
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top