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?
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.
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
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?
Thanks, that should work well. I appreciate it.
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