I have file services.py with certain class MyCache in it. All instances of MyCache should share one "cache" field, so I made it static. In order to initialize cache there is static method that loads it. This method is called exactly once at the very start of the app.
The problem is that when I import services.py from other .py file and create instance of MyCache - it prints that cache is empty!
How can I fix it and make "cache" field shared by all instances of the class disregard of place from which they are created?
I can't get why this happens. Please help :)
services.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
main.py:
import services
if __name__ == '__main__':
services.MyCache.initialize()
other_file.py:
import services
services.MyCache().foo() # creates instance, prints 0 in MyCache.__init__
The values of the list are called items or elements. Python list can contain the same value multiple times, unlike set. Each occurrence is considered a different item. Initialize a list using square brackets. Initialize using list () function. You can use square brackets to initialize an empty list in Python.
In an application embedding Python, this should be called before using any other Python/C API functions; see Before Python Initialization for the few exceptions. This initializes the table of loaded modules ( sys.modules ), and creates the fundamental modules builtins, __main__ and sys. It also initializes the module search path ( sys.path ).
See also Python Initialization Configuration. In an application embedding Python, the Py_Initialize () function must be called before using any other Python/C API functions; with the exception of a few functions and the global configuration variables. The following functions can be safely called before Python is initialized:
To customize the fields in the python data class, we will have to import fields from the data classes module. Now we can customize the fields. There are six optional parameters that can be set to customize the field properties. Let’s take a look at each parameter.
#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)
Here we are just using a python module as a singleton. To learn more about how python caches modules so they are only initialized once, read here: https://docs.python.org/2/library/sys.html#sys.modules
One problem is that you have modules using the class during import before execution has reached the if __name__ == '__main__:
part that does the initialization.
You can use a classmethod
to initialize the class-level cache dynamically on first use. Add a lock and it is also thread-safe. You no longer need to initialize specifically in __main__
, which is easy to forget, and you can use it at any time by other importers.
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With