By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,050 Members | 1,020 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,050 IT Pros & Developers. It's quick & easy.

Writing an immutable object in python

P: n/a
Hi,

I've noticed that if I initialize list of integers in the next manner:
my_list = [0] * 30
It works just fine, even if I'll try to assign one element:
id( my_list[4] ) 10900116 id( my_list[6] ) 10900116 my_list[4] = 6
id( my_list[4] ) 10900044 id( my_list[6] )

10900116

The change in the poision occurs becouse int() is an immutable object.

if I will do the same with a user-defined object, This reference
manipulating will not happen. So, every entry in the array will refer
to the same instance.

Is there a way to bypass it (or perhaps to write a self-defined
immutable object)?

Oct 17 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
> The change in the poision occurs becouse int() is an immutable object.

if I will do the same with a user-defined object, This reference
manipulating will not happen. So, every entry in the array will refer
to the same instance.

Is there a way to bypass it (or perhaps to write a self-defined
immutable object)?


This has nothing to do with int being mutable or not. It only has to do
with _list_ being mutable, and of course teh semantics of the

_ * _ : list x int -> list

operator, which simply shallow copies the list. So assigning to some

l[i]
will replace that entry - regardless of what is stored there. And that
is all you do. The mutablity of an object only comes into place if you
try and do

l[i].some_mutating_op()

That catches many people by surprise - but you don't do such a thing :)

And besides: making an object immutable would mean that the only way to
create an instance would be the constructor - rendering the purpose of
the whole exercise somewhat moot - as then you'd have to call the
constructor individually for each index you want to alter anyway. Which
you have to do in the case of mutable objects, too. So - no gain there.

Regards,

Diez
Oct 17 '05 #2

P: n/a
In article <11**********************@g14g2000cwa.googlegroups .com>,
"Mapisto" <ma*****@gmail.com> wrote:
I've noticed that if I initialize list of integers in the next manner:
my_list = [0] * 30
It works just fine, even if I'll try to assign one element:
id( my_list[4] ) 10900116 id( my_list[6] ) 10900116 my_list[4] = 6
id( my_list[4] ) 10900044 id( my_list[6] )
10900116

The change in the poision occurs becouse int() is an immutable object.

if I will do the same with a user-defined object, This reference
manipulating will not happen. So, every entry in the array will refer
to the same instance.


Not at all. If you do the same thing,
class C:
pass
c = C()
a = [c]*12

.... etc., you should observe the same pattern with respect to
object identities. Mutability doesn't really play any role here.
Is there a way to bypass it (or perhaps to write a self-defined
immutable object)?


Bypass what? What do you need?

Donn Cave, do**@u.washington.edu
Oct 17 '05 #3

P: n/a
Mapisto wrote:
Hi,

I've noticed that if I initialize list of integers in the next manner:

my_list = [0] * 30

It works just fine, even if I'll try to assign one element:

id( my_list[4] )
10900116
id( my_list[6] )
10900116
my_list[4] = 6
id( my_list[4] )
10900044
id( my_list[6] )
10900116

The change in the poision occurs becouse int() is an immutable object.
No, it happens because you assign my_list[4] to a different object.
Obviously, 0 and 6 can't be located in the same place in RAM.

The difference lies in doing something like "my_list[n] = X" rather
than changing the state of a shared existing object as in something
like "my_list[n].f(X)".
if I will do the same with a user-defined object, This reference
manipulating will not happen.


Really?
class C: .... pass
.... my_list = [C()]*30
id(my_list[4]) 1003056 id(my_list[6]) 1003056 my_list[4] = C() # Another instance
id(my_list[4]) 986048 id(my_list[6])

1003056
Oct 17 '05 #4

P: n/a
Ok, I've understood my mistake.

Now, my list contains a shared entry of an empty object. When an entry
is needed to be changed, I check if the entry is the shared empty
object; in that case I create a new unique instance. If the entry is
already a unique instance, I use it, so the empty object isn't touched.
Thanks,
Guy.

Oct 18 '05 #5

P: n/a
Mapisto wrote:
Ok, I've understood my mistake.

Now, my list contains a shared entry of an empty object. When an entry
is needed to be changed, I check if the entry is the shared empty
object; in that case I create a new unique instance. If the entry is
already a unique instance, I use it, so the empty object isn't touched.


It's probably less confusing if you make a list
of None, instead of a list of references to an
instance object you don't use anyway.
Oct 20 '05 #6

P: n/a
Mapisto wrote:
Ok, I've understood my mistake.

Now, my list contains a shared entry of an empty object. When an entry
is needed to be changed, I check if the entry is the shared empty
object; in that case I create a new unique instance. If the entry is
already a unique instance, I use it, so the empty object isn't touched.


If you know that you'll use all list entries, you
might as well do it right from the start. Instead
of:

l = [C()] * n

you can do:

l = [C() for i in range(n)]

Oct 20 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.