Copy with __slots__...will it ever work?

Alex Martelli aleax at aleax.it
Fri Mar 28 06:39:33 EST 2003


Andrew Sterian wrote:

> I've run up against the problem of not being able to call copy.copy()
> on a new-style class that defines __slots__. I found the thread that

Do you mean on an INSTANCE of the class, or on the class itself as
you say?  Copying classes (even by deepcopy) has long had weird
behavior -- in 2.2 for a class X, copy.copy(X) is X (even though
X is mutable), copy.deepcopy(X) raises; in 2.3, copy.deepcopy(X)
is X (weird, for a mutable object).  Of course it makes no difference
here whether X defines __slots__ or not -- that constrains the
attributes of INSTANCES of the class, NOT attributes of the class
itself.  So -- if you're actually discussing copying *instances*
of classes of some kind or other, see the other subthread (basically:
fixed in the 2.3 version currently in CVS); if you actually mean
what you say and want to copy *classes*, the issue is deeper and
murkier and I would suggest trying a different approach.

I'm not being uselessly pedantic, please note: since classes ARE
"first-class objects" in Python, you can subject them to all
kinds of operations (or at least TRY to;-), so saying "doing
something to a class" and "doing something to instances of a
class" are BOTH valid things, and two VERY different ones.  People
whose background is in languages where classes AREN'T "first-class
objects", such as C++, often trip on this terminology issue.


> IMHO, the ideas of slots and copying a class are orthogonal, so I

They are -- but copying INSTANCES of the class isn't all that
orthogonal, because if the class defines __slots__ then its
instances hold state in a completely different way from how
instances of other kinds of classes hold it.

> don't see why it shouldn't be as easy as just calling copy.copy() and
> having it work. In other words, what does restricting attribute access
> have to do with copying those attributes?

"restricting" per se doesn't (e.g. you can implement __setattr__
and __getattribute__ to perform such restrictions, without
necessarily impacting copying -- trickier than one might think,
but doable).  But __slots__ isn't so much about "restricting" as
about a specific memory optimization: holding per-instance state,
NOT in a dictionary, as in the normal case (flexible, fast, but
a big expense of memory for objects that get instantiated HUGE
numbers of times), but in dedicated "slots" (with fixed names)
in the instance object.

Perhaps this makes it easier to see why "changing the strategy
that instances use to keep their state" can easily interfere
with "how to copy all the state of an instance".  Not an intentional
design decision, but a well-understandable bug (now fixed).


Alex





More information about the Python-list mailing list