我来自C ++背景,并且经常使用静态变量来减少必须初始化的时间变量的数量(特别是如果初始化需要很长时间)。因此,从StackOverflow上的其他帖子中,人们建议使用静态类变量,如下所示:
class MyClass(object):
StaticList1 = [...] # Very large list
StaticList2 = [...] # Very large list
现在,如果在程序执行过程中至少存在一个MyClass实例并且列表只创建一次,那么这很好。但是,如果在执行的某个阶段没有MyClass的实例,Python似乎删除了静态列表(我假设因为引用计数器降为0)。
所以我的问题是,如果没有使用外部模块初始化StaticList1和StaticList2一次(第一次使用它们)并且永远不会删除它们,即使在程序存在之前没有MyClass的实例,也没有任何简单的方法(或者你手动删除列表??
编辑:
也许我过分简化了这个问题。我在做什么:
class MyClass(object):
StaticList = None
def __init__(self, info):
if self.StaticList == None:
print "Initializing ..."
self.StaticList = []
# Computationally expensive task to add elements to self.StaticList, depending on the value of parameter info
def data(self):
return self.StaticList
我从另一个脚本导入模块并有一个这样的循环:
import myclass
for i in range(10000):
m = myclass.MyClass(i)
d = m.data()
# Do something with d.
静态列表的初始化大约需要200到300毫秒,并且在循环的每次迭代中执行,因此循环需要很长时间才能完成。
答案 0 :(得分:3)
虽然您的类确实有一个名为StaticList
的静态字段,但您实际上正在初始化并使用同名的实例字段,因为您有self
限定符使用。我认为如果您使用MyClass.StaticList
初始化并访问它,您的代码将正常工作。
通常,通过Python的名称查找,您可以通过实例访问类字段,就好像它是该实例上的实例字段(例如self.StaticList
),只要您实际上并没有在该实例上设置同名的实例字段。从那一刻起,实例字段会影响类字段(即self.StaticList
会找到您的新值,而MyClass.StaticList
仍会引用您的类值。
作为解说员新鲜的例子:
>>> class A(object):
... v=2 # static initialization
...
>>> A.v
2
>>> a=A() # get an instance, and
>>> a.v # get the static value via the instance:
2
>>> a.v = 7 # but now set 'v' on the instance, and ...
>>> a.v # we will get the instance field's value:
7
>>> A.v # the static value is still the old:
2
>>> b=A() # and other instances of the class ...
>>> b.v # will use the same old static value:
2
实例变量a.v
最初等于A.v
,但通过明确设置a.v=7
,您将在该实例中“分离”它们。
虽然这意味着,原则上,你可以使用静态类字段MyClass.Values
以及同名的实例字段xyz.Values
,这是经常因这种混乱而气馁。
作为单独的评论,您可以考虑将data
方法注释为@staticmethod
(并移除移动中的self
参数),并将其称为MyClass.data()
事实清楚的是,你会在每次通话时回到同一个列表实例。