在Python中只初始化一次字段

2024-06-09 01:19:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有档案服务.py其中包含特定的类MyCache。MyCache的所有实例都应该共享一个“cache”字段,因此我将其设为静态的。为了初始化缓存,有一个加载缓存的静态方法。此方法在应用程序开始时只调用一次。在

问题是当我进口服务.py从其他.py文件创建MyCache实例-它打印出缓存是空的!在

如何修复它并使类的所有实例共享“cache”字段而不考虑它们是从何处创建的?在

我不明白为什么会这样。请帮助:)

在服务.py公司名称:

class MyCache:
    cache = {}

    @staticmethod
    def initialize():
       MyCache.cache = load_from_file()
       print(len(MyCache.cache)) # prints 3

    def __init__(self):
       print(len(MyCache.cache)) # supposed to print 3, because initialize has been called earlier, but prints 0 when called from other_file.py

在主.py公司名称:

^{pr2}$

其他_文件.py公司名称:

import services

services.MyCache().foo() # creates instance, prints 0 in MyCache.__init__

Tags: 实例frompy名称cacheleninitdef
3条回答
    class MyCache:
        cache = {}
        __initialized = False

        @staticmethod
        def initialize():
           if not MyCache.__initialized:
               MyCache.cache = load_from_file()
               MyCache.__initialized = True

        def __init__(self):
           print(len(MyCache.cache)) 

一个问题是,在执行到达执行初始化的if __name__ == '__main__:部分之前,有模块在导入期间使用该类。在

您可以使用classmethod在第一次使用时动态初始化类级缓存。添加一个锁,它也是线程安全的。您不再需要在__main__中特别初始化,这很容易忘记,并且您可以随时由其他导入程序使用它。在

import threading

class MyCache:
    cache = None
    _lock = threading.Lock()

    @classmethod
    def initialize(cls):
       with cls._lock:
           if cls.cache is None:
               cls.cache = load_from_file()

    def __init__(self):
       self.initialize()       
       print(len(MyCache.cache))
#mycache.py
def load_from_file():
    pass
    ...
cache = load_from_file()

#anotherlib.py
from mycache import cache

...

#main.py
from anotherlib import ... #(Now the cache is initialized)
from mycache import cache #(Python looksup the mycache module and doesn't initialize it again)

这里我们只使用python模块作为单例。要了解python如何缓存模块以使它们只初始化一次,请阅读以下内容:https://docs.python.org/2/library/sys.html#sys.modules

相关问题 更多 >