简体   繁体   中英

Python list of variables inside a class

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?

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[0]
                      +----+


                      +----+
            l[0] ---> | 42 |
                      +----+

                      +---+
            a ------> | 0 |
                      +---+

Notice that l[0] has not changed.

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:

  • You're grabbing an instance of 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.
  • Inherit from object to get a "new-style" class. Trust me on this, there is essentially no reason to be using an old-style class nowadays.
  • Naming conventions. Classes start with upper case letters.

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM