Pythonic初始化(复杂)静态数据成员的方法

时间:2009-05-16 18:20:30

标签: python class

我有一个具有复杂数据成员的类,我想保持“静态”。我想用函数初始化一次。 Pythonic如何是这样的:

def generate_data():
    ... do some analysis and return complex object e.g. list ...

class Coo:
    data_member = generate_data()
    ... rest of class code ...

函数generate_data需要很长时间才能完成并返回在正在运行的程序范围内保持不变的数据。我不希望每次Coo实例化时都会运行它。

另外,要验证,只要我没有在data_member中为__init__分配任何内容,它就会保持“静态”状态吗?如果Coo中的方法将某个值附加到data_member(假设它是一个列表),那么该添加是否可用于其他实例?

由于

3 个答案:

答案 0 :(得分:15)

你是对的。 data_member将创建一次,并且可供coo的所有实例使用。如果任何实例修改它,那么所有其他实例都可以看到该修改。

这是一个演示所有这一切的示例,其结果显示在最后:

def generate_data():
    print "Generating"
    return [1,2,3]

class coo:
    data_member = generate_data()
    def modify(self):
        self.data_member.append(4)

    def display(self):
        print self.data_member

x = coo()
y = coo()
y.modify()
x.display()

# Output:
# Generating
# [1, 2, 3, 4]

答案 1 :(得分:14)

正如其他人已经回答你是对的 - 我还要再添加一件事:如果一个实例修改了对象coo.data_member本身,例如

self.data_member.append('foo')

然后其他实例看到修改。但是,如果你这样做

self.data_member = new_object

然后创建一个新的实例成员,该成员将覆盖该类成员,并且只对该实例可见,而不是对其他实例可见。差异并不总是很容易发现,例如self.data_member += 'foo'self.data_member = self.data_member + 'foo'

为避免这种情况,您可能应始终将对象称为coo.data_member(而不是self)。

答案 2 :(得分:6)

执行data_member = generate_data()时,语句class coo: ...只会执行一次。在大多数情况下,类语句发生在模块级别,并在导入模块时执行。因此,当您第一次导入具有类data_member = generate_data()的模块时,coo将仅执行一次。

coo课程的所有实例都会共享data_member,并可以通过撰写coo.data_member来访问它。任何coo.data_member实例都会立即显示对coo所做的任何更改。实例可以拥有自己的data_member属性。可以通过键入self.data_member = ...来设置此属性,该属性仅对该实例可见。仍可通过键入data_member来访问“静态”coo.data_member