Pythonic方式初始化(复杂)静态数据成员
我有一个类,里面有一个复杂的数据成员,我想让它保持“静态”。我想用一个函数来初始化它,只需要初始化一次。像这样的做法在Python中算不算好呢:
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 的实例时都运行这个函数。
另外,我想确认一下,只要我在 __init__
方法中不对 data_member
进行赋值,它就会保持“静态”状态,对吧?如果 Coo 类中的某个方法往 data_member
(假设它是一个列表)添加了一些值,这个添加的值会对其他实例可用吗?
谢谢
3 个回答
这段代码 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
来访问。
正如其他人所说,你说得对——我再补充一点需要注意的:如果一个实例修改了对象的 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
。
你说得完全正确。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]