简体   繁体   English

类中的Python变量列表

[英]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: 无论如何,我正在构建一个程序,该程序涉及在Python 2.7中使用四色定理为地图着色,并尝试尽可能多地使用某些颜色,并且在运行类似以下代码的代码时遇到问题:

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. ...尽管该程序在主程序中进行了更改,但该程序仍打印0。 Any thoughts on how to update instance.variable_list with the change? 关于如何通过更改来更新instance.variable_list的任何想法?

You have to think of Python variables in terms of pointers. 您必须根据指针来考虑Python变量。 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 . 答案是否定的,因为重新分配a与列表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 ). l[0]恰好指向与a (int 42 )相同的对象。 When we reassign a , we simply have it "point" to a new object in memory (the int 0 ). 当我们重新分配a ,我们只是简单地让它“指向”内存中的一个新对象(int 0 )。 This has no bearing on the list l . 这与列表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. 请注意, l[0]尚未更改。

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. 您要获取State的实例,因此使属性成为实例属性,而不是类属性。 I doubt you want every instance of State to share the same attributes. 我怀疑您是否希望State每个实例共享相同的属性。
  • @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. @property装饰器使之成为可能,因此您可以像访问常规variable_list一样访问variable_list ,但是可以自定义其返回值的行为-在这种情况下,是几个实例属性。
  • Inherit from object to get a "new-style" class. object继承以获得“新样式”类。 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. 当您更新变量a它不会更新该实例,而只是为其分配具有完全不同的指针的另一个int。 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: 您可以在列表中添加执行以下操作的update方法:

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]. a变为0,b变为0。因此,列表“ variable_list”变为[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]! 对象实例中的变量确实为1。但是,variable_list仍为[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). 为了解决这个问题,您可以使函数根据a和b的当前值(而不是原始值)来更新variable_list。 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. 当您使用instance.updateVariableList()调用该函数时,它将基于a和b的当前值更新列表的值。 Now print instance.variable_list[0] will show the updated values. 现在打印instance.variable_list [0]将显示更新的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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