Reputation: 25
this is my first question, and combined with my being fairly noob feel free to tell me if there is a completely different way I should be going about this!
Anyways, I am building a program that involves coloring a map with the four color theorem in Python 2.7, attempting to use certain colors as much as possible, and I ran into a problem when running something like this code:
In one module:
class state:
a = 0
b = 0
variable_list = [a,b]
Then I import that module into my main program:
from State import state //State(uppercase "s") is the .py file with the state class in it
instance = state()
instance.a = 1
print instance.variable_list[0]
...and the program prints 0, despite changing it in the main program. Any thoughts on how to update instance.variable_list with the change?
Upvotes: 2
Views: 1006
Reputation: 25954
I'll cut to what I think you want to be doing.
class State(object):
def __init__(self):
self.a = 0
self.b = 0
@property
def variable_list(self):
return self.a, self.b
and usage:
state = State()
state.a = 1
state.variable_list
Out[23]: (1, 0)
Notable changes from your code:
State
, so make the attributes instance attributes, not class attributes. I doubt you want every instance of State
to share the same attributes.@property
decorator makes it so you can access variable_list
just like it's a regular attribute, but you can customize the behavior of what it returns - in this case, a couple of instance attributes.object
to get a "new-style" class. Trust me on this, there is essentially no reason to be using an old-style class nowadays.Upvotes: 2
Reputation: 32189
When you update the variable a
it does not update that instance but simply assigns it a different int with a completely different pointer. Therefore, this change does not reflect that change in the list as you expected it would.
You could either add a update
method in your list that does:
def update():
variable_list = [a,b]
and call it every time you update your variables.
Or, you could simply use a dictionary and do away with individual variables:
class state:
variables = {'a': 0, 'b': 1}
x = state()
print x.variables['a']
x.variables['a'] = 1
print x.variables['a']
[OUTPUT]
0
1
Upvotes: 0
Reputation: 129507
You have to think of Python variables in terms of pointers. Your question really boils down to the following:
>>> a = 42
>>> l = [a]
>>> a = 0
>>> print l[0] # shouldn't this print 0?
42
The answer is no, because re-assigning a
has nothing to do with the list l
. The list contains pointers to certain objects in memory. l[0]
happens to be pointing to the same object as a
(the int 42
). When we reassign a
, we simply have it "point" to a new object in memory (the int 0
). This has no bearing on the list l
.
It looks like this:
a = 42 l = [a] +----+ a -----> | 42 | <------ l[0] +----+ a = 0 +----+ l[0] ---> | 42 | +----+ +---+ a ------> | 0 | +---+
Notice that l[0]
has not changed.
Upvotes: 2
Reputation: 376
Let's take a look at your class code.
class state:
a = 0
b = 0
variable_list = [a,b]
a becomes 0, b becomes 0. Therefore, the list "variable_list" becomes [0, 0]. You then proceeded to change a using this code:
instance.a = 1
Which worked. The objects instance a variable is indeed 1. However, variable_list is still [0, 0]! The list remained it's original value because the list itself wasn't changed. The code you ran to make the list is only ran once. To solve this, you can make a function to update variable_list based on the current values of a and b (not the original values). For instance you can make a function to update the variable list like so:
def updateVariableList(self):
variable_list = [self.a, self.b]
when you call that function using instance.updateVariableList(), it will update the values of the list based on the current values of a and b. Now print instance.variable_list[0] will show the updated values.
Upvotes: 0