Python类内部变量的列表

2 投票
4 回答
992 浏览
提问于 2025-04-18 05:04

这是我第一次提问,因为我还是个新手,所以如果有完全不同的方法,请随便告诉我!

总之,我正在用Python 2.7编写一个程序,目的是给地图上色,遵循四色定理,尽量使用特定的颜色。但是在运行类似下面的代码时,我遇到了一个问题:

在一个模块中:

class state:
    a = 0
    b = 0
    variable_list = [a,b]

然后我把这个模块导入到我的主程序中:

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]

...结果程序打印出0,尽管我在主程序中已经进行了更改。你们有什么想法,如何更新instance.variable_list以反映这个变化吗?

4 个回答

0

当你更新变量 a 时,它并不会更新原来的那个实例,而是给它分配了一个完全不同的整数和指针。所以,这个变化并不会像你预期的那样反映在列表中。

你可以在你的列表中添加一个 update 方法,内容是:

def update():
    variable_list = [a,b]

然后每次你更新变量时都调用这个方法。

或者,你也可以直接使用字典,这样就不需要单独的变量了:

class state:
    variables = {'a': 0, 'b': 1}

x = state()
print x.variables['a']

x.variables['a'] = 1
print x.variables['a']

[OUTPUT]
0
1
2

我直接说说我认为你想要做的事情。

class State(object):
    def __init__(self):
        self.a = 0
        self.b = 0
    @property
    def variable_list(self):
        return self.a, self.b

以及用法:

state = State()

state.a = 1

state.variable_list
Out[23]: (1, 0)

你代码中值得注意的变化:

  • 你在获取一个State的实例,所以要把属性设置为实例属性,而不是类属性。我想你不希望每个State的实例都共享同样的属性。
  • @property装饰器让你可以像访问普通属性一样访问variable_list,但你可以自定义它返回的内容——在这个例子中,是几个实例属性。
  • object继承,以获得一个“新式”类。相信我,现在几乎没有理由使用旧式类。
  • 命名规范。类名要以大写字母开头。
2

你可以把Python中的变量想象成指针。你的问题其实可以简单归结为以下几点:

>>> a = 42
>>> l = [a]
>>> a = 0
>>> print l[0]  # shouldn't this print 0?
42

答案是否定的,因为重新给a赋值和列表l没有关系。这个列表里面存的是指向内存中某些对象的指针。l[0]恰好指向和a相同的对象(也就是数字42)。当我们重新给a赋值时,其实只是让它“指向”内存中的一个新对象(数字0)。这对列表l没有影响。

它的情况是这样的:

a = 42
l = [a]

                      +----+
            a  -----> | 42 | &lt------ l[0]
                      +----+

a = 0

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

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

注意到l[0]并没有改变。

0

让我们来看看你的类代码。

class state:
    a = 0
    b = 0
    variable_list = [a,b]

这里,a 和 b 都变成了 0。所以,列表 "variable_list" 变成了 [0, 0]。接着,你用这段代码修改了 a:

instance.a = 1

这段代码是有效的。对象实例中的 a 确实变成了 1。但是,variable_list 仍然是 [0, 0]!这个列表保持了它最初的值,因为列表本身没有被改变。你用来创建这个列表的代码只运行了一次。为了解决这个问题,你可以写一个函数,根据 a 和 b 的当前值(而不是原始值)来更新 variable_list。比如,你可以这样写一个更新变量列表的函数:

def updateVariableList(self):
    variable_list = [self.a, self.b]

当你调用这个函数,比如 instance.updateVariableList(),它会根据 a 和 b 的当前值来更新列表的值。现在,打印 instance.variable_list[0] 就会显示更新后的值。

撰写回答