goo*_*ons 2 python static class
我来自 C++ 背景并且经常使用静态变量来减少必须初始化变量的时间数量(特别是如果初始化需要很长时间)。因此,从 StackOverflow 上的其他帖子中,人们建议使用静态类变量如下:
class MyClass(object):
StaticList1 = [...] # Very large list
StaticList2 = [...] # Very large list
Run Code Online (Sandbox Code Playgroud)
现在,如果在整个程序执行过程中至少存在 1 个 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
Run Code Online (Sandbox Code Playgroud)
我从另一个脚本导入模块并有一个这样的循环:
import myclass
for i in range(10000):
m = myclass.MyClass(i)
d = m.data()
# Do something with d.
Run Code Online (Sandbox Code Playgroud)
静态列表的初始化大约需要 200 - 300 毫秒,并且在循环的每次迭代中执行,因此循环需要很长时间才能完成。
虽然您的类确实有一个名为 的静态字段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
Run Code Online (Sandbox Code Playgroud)
实例变量a.v最初等于A.v,但通过显式设置a.v=7,您在该实例中“分离”了它们。
虽然这意味着,原则上,您可以使用静态类字段MyClass.Values以及xyz.Values同名的实例字段,但由于这种混淆,通常不鼓励这样做。
作为单独的评论,您可以考虑将该data方法注释为 a @staticmethod(并删除self移动中的参数)并调用它,MyClass.data()以使事实更清楚,您将在每次调用时返回相同的列表实例。