This code is not thread safe.
Stream Security Definition
You can check the thread safety by going through the bytecode, for example:
from dis import dis dis('a = [] \n' 'a.append(5)')
However, I have to warn that bytecode may change over time, and thread safety may depend on the python you use (cpython, jython, ironpython, etc.)
So, the general recommendation, if you ever need thread safety, uses synchronization mechanisms: locks, queues, semaphores, etc.
Thread-safe version of LazyProperty
Thread safety for the descriptor you mentioned can be summarized as follows:
from threading import Lock class LazyProperty(object): def __init__(self, func): self._func = func self.__name__ = func.__name__ self.__doc__ = func.__doc__ self._lock = Lock() def __get__(self, obj, klass=None): if obj is None: return None
Canonical Stream Initialization
To canonically initialize a stream sequence, you need to encode a metaclass that receives a lock at creation time and is freed after instantiation:
from threading import Lock class ThreadSafeInitMeta(type): def __new__(metacls, name, bases, namespace, **kwds):
Something completely different than metaclass solutions
And finally, if you need a simpler solution, just create a generic init lock and instantiate using it:
from threading import Lock MyCls._inst_lock = Lock()
However, it is easy to forget, which can lead to very interesting debugging times. You can also code a class decorator, but, in my opinion, it would not be better than a metaclass solution.