Instantiation of 2nd object appends 1st?

Alex Martelli aleaxit at yahoo.com
Wed Nov 8 09:51:08 EST 2000


"Carl Bray" <cbray at orchestream.com> wrote in message
news:973680201.294555 at lave...
>
> In the following code A is instantiated with a list. A assigns the list to
> the attribute A_list.

No it doesn't -- it *appends* the list argument to the attribute A_list:

> class A:
>   A_list = []
>   def __init__(self, the_list):
>     # Append the list to A's list
>     self.A_list.append(the_list)

...and said attribute is a class-attribute (shared by all instances)
rather than an instance-attribute.

If you want to perform exactly what you just wrote, the code is:

class A:
    def __init__(self, the_list):
        self.A_list = the_list


Take care, though: this DOES assign (bind) *exactly* the list object
that is passed in during construction; not a *copy* of that object,
but *exactly THAT object*.  A list is a mutable object; therefore,
after, e.g.:

x = [1,2,3]
y = A(x)
x.append(4)

y.A_list will now be [1,2,3,4].  The *contents* of y.A_list will
be exactly the same as the *contents* of x, at any point in time
(until either one of them is re-bound to something else, or goes
away), since the *identity* of the objects is also the same.


This may be what you want, in which case, fine!  But if you want
to *copy the contents of the list argument into a brand-new list
object* to be assigned (bound) to self.A_list, then you can also
choose to do that, explicitly:

class A:
    def __init__(self, the_list):
        self.A_list = the_list[:]

The [:] notation indicates "a slice from the beginning to the end",
i.e., a copy of the list object's contents.  You may use this
notation for all kinds of sequences, but it's only important for
lists among the built-in ones (not for strings or tuples, since
those are immutable anyway -- so, there's no need to copy the
contents, since said contents cannot "change later" anyway).

One more note in the same vein...: the [:] notation only copies
the "top level" of the list.  If some of the list's items are
themselves mutable (not numbers, strings, or tuples), then the
same "changes made through one reference are 'picked up' by ALL
reference, since object-identity is shared" issue may come up
for them.  If this might be a problem for you, look up the
builtin module 'copy', and specifically its copy.deepcopy()
function -- that one makes 'actual' copies, recursively, until
it gets down to items that can't/shouldn't/need not be copied...


Alex






More information about the Python-list mailing list