Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Don't understand behavior; instance form a class in another class' instance

0 views
Skip to first unread message

Martin P. Hellwig

unread,
Mar 25, 2010, 7:29:09 PM3/25/10
to
Hi all,

When I run the following snippet (drastically simplified, to just show
what I mean):
>>
import platform, sys

class One(object):
def __init__(self):
self.one = True

def change(self):
self.one = False

class Two(object):
def __init__(self):
self._instance_one = One()
self.one = self._instance_one.one
self.change = self._instance_one.change

if __name__ == '__main__':
print(sys.version)
print(platform.machine())
print(80*'#')
TEST1 = One()
print(TEST1.one)
TEST1.change()
print(TEST1.one)
TEST1 = None
print(80*'#')
TEST2 = Two()
print(TEST2.one)
TEST2.change()
print(TEST2.one
>>

I get the following result:

<<
[GCC 4.2.1 20070719 [FreeBSD]]
amd64
################################################################################
True
False
################################################################################
True
True
################################################################################
<<

What I don't understand why in the second test, the last boolean is True
instead of (what I expect) False.
Could somebody enlighten me please as this has bitten me before and I am
confused by this behavior.

Thanks in advance

--
mph

Christian Heimes

unread,
Mar 25, 2010, 7:41:57 PM3/25/10
to pytho...@python.org
Martin P. Hellwig schrieb:

> What I don't understand why in the second test, the last boolean is True
> instead of (what I expect) False.
> Could somebody enlighten me please as this has bitten me before and I am
> confused by this behavior.

Hint: TEST2.one is not a reference to TEST2.__instance_one.one. When you
alter TEST2.__instance_one.one you don't magically change TEST2.one,
too. Python doesn't have variables like C pointers. Python's copy by
object (or share by object) behavior can be understand as labels. The
label TEST2.one references the same object as TEST2.__instance_one.one
until you change where the label TEST2.__instance_one.one points to.

Christian

Martin P. Hellwig

unread,
Mar 25, 2010, 8:06:06 PM3/25/10
to

Ah okay thanks for the explanation, Am I correct in thinking (please
correct me if I mangle up the terminology and/or totally are in the
wrong ballpark) that this is more or less because the label of the first
class is to an object (boolean with value False)
and the label of the second class does not cascade to the first label
for looking something up but instead during assignment sees that it is a
label to an object instead of the object itself thus copies the label
content instead?

I probably expected classes namespaces to behave in about the same way
as lists and dictionaries do, don't know where I picked that up.

Thanks again,

--
mph

Rhodri James

unread,
Mar 25, 2010, 9:10:36 PM3/25/10
to

Pretty much. In the sense that you're thinking of, every assignment works
that way, even the initial "TEST1 = One()". Assignment binds names to
objects, though you have to be aware that names can be such exotic things
as "t", "a[15]" or "TEST2.__instance_one.one"

> I probably expected classes namespaces to behave in about the same way
> as lists and dictionaries do, don't know where I picked that up.

They do, in fact, which isn't terribly surprising considering that class
namespaces are implemented with dictionaries. The distinction you're
missing is that lists and dictionaries are mutable, while booleans aren't;
you can change the contents of a dictionary, but you can't change the
'contents' of a boolean.

--
Rhodri James *-* Wildebeeste Herder to the Masses

Martin P. Hellwig

unread,
Mar 25, 2010, 9:56:38 PM3/25/10
to
On 03/26/10 01:10, Rhodri James wrote:
<cut>

>
> Pretty much. In the sense that you're thinking of, every assignment
> works that way, even the initial "TEST1 = One()". Assignment binds names
> to objects, though you have to be aware that names can be such exotic
> things as "t", "a[15]" or "TEST2.__instance_one.one"
>
>> I probably expected classes namespaces to behave in about the same way
>> as lists and dictionaries do, don't know where I picked that up.
>
> They do, in fact, which isn't terribly surprising considering that class
> namespaces are implemented with dictionaries. The distinction you're
> missing is that lists and dictionaries are mutable, while booleans
> aren't; you can change the contents of a dictionary, but you can't
> change the 'contents' of a boolean.
>

All makes sense now, thanks Rhodri & Christian.

--
mph

0 new messages