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

passing class by reference does not work??

0 views
Skip to first unread message

wswilson

unread,
Apr 11, 2007, 10:23:59 AM4/11/07
to
Here is my code:

class A():
val = 0

def b(item, a):
a.val = a.val + 1
return item + a.val

def c():
d = [1, 2, 3]
print [b(item, A()) for item in d]

c()

I expected this to output [2, 4, 6]. However, it outputs [2, 3, 4]
which is not what I wanted. I thought that if I passed the A()
instance in my list comprehension in c(), then the changes I made to
a.val in b() would be reflected in the A() instance next time the list
comprehension called b(). But, obviously that is not happening. I'm
kinda new at python so I may be missing something obvious here.

Any suggestions?

antred

unread,
Apr 11, 2007, 10:36:50 AM4/11/07
to

> def b(item, a):
> a.val = a.val + 1
> return item + a.val


This is where the problem lies, specifically the line a.val = a.val +
1
What happens here is that the 1st a.val refers to a member of the
class instance a, called val ... which does not yet exist and is
therefore created as the result of taking the val member of the class
A and adding 1 to it. In other words, a.val is not the same variable
as A.val. Are you following? If not, change your b() method to this:

def b(item, a):
a.val = a.val + 1

assert a.val is A.val
return item + a.val

and see what happens.

Alex Martelli

unread,
Apr 11, 2007, 10:40:17 AM4/11/07
to
wswilson <wswi...@gmail.com> wrote:

Yep:

a.val = a.val + 1

sets in INSTANCE variable a the value computed on the RHS. A.val (the
CLASS variable) is never changed. You're not "passing the class", of
course, but rather an instance of the class.

To increment A.val, you need to assign to the class variable, or write
some method in class A which assigns to the class variable. If you
want, you can change class A only, leaving all of the rest of your code
untouched, with a property (but then A needs to be newstile), e.g.:

class A(object):
_val = 0
def getval(self): return A._val
def setval(self, value): A._val = value
val = property(getval, setval)

now your code should work as intended: any read access to a.val returns
A._val, and any setting of a.val actually sets A._val, as you appear to
desire.


Alex

wswilson

unread,
Apr 11, 2007, 10:42:14 AM4/11/07
to

OK, I see that. I thought I was creating an instance of the class A()
when I called the list comprehension and that the a parameter in b()
was then a reference to that instance. What can I do instead?

wswilson

unread,
Apr 11, 2007, 10:48:57 AM4/11/07
to
On Apr 11, 10:40 am, a...@mac.com (Alex Martelli) wrote:

Thanks, that should work well. I appreciate it.

Hamilton, William

unread,
Apr 11, 2007, 10:49:56 AM4/11/07
to wswilson, pytho...@python.org

A() is not the class A. It calls the constructor of class A, returning
an instance. If you change that line to:

print [b(item, A) for item in d]

you'll get the output you expected.

---
-Bill Hamilton
wha...@entergy.com

0 new messages