Threading of Periodic Update to Class Member
<p>What is a method for updating a class member in Python while it is still being used by other methods in the class?</p>

<p>I want the rest of the class to continue processing using the old version of the member until it is fully updated and then switch all processing to the new version once the update is complete.</p>

<p>Here is a toy example to illustrate my use case, where <code>self.numbers</code> is the class member that needs safely threaded periodic updating using the logic in <code>updateNumbers()</code>, which I want called in a non-blocking way by <code>runCounter()</code>. </p>

<pre><code>from time import sleep, time

class SimpleUpdater(object):
    def __init__(self):
        self.i = 5
        self.numbers = list(range(self.i))
        self.lastUpdate = time()
        self.updateDelta = 10

    def timePast(self):
        now = time()
        delta = self.lastUpdate - now
        return (delta &gt; self.updateDelta)

    def updateNumbers(self):
        print('Starting Update', flush=True)
        self.numbers = list(range(self.i))
        # artificial calculation time
        sleep(2)
        print('Done Updating', flush=True)

    def runCounter(self):
        for j in self.numbers:
            print(j, flush=True)
            sleep(0.5)
        self.i += 1
        if self.timePast:
            ## Spin off this calculation!! (and safely transfer the new value)
            self.updateNumbers()

if __name__ == '__main__':
    S = SimpleUpdater()
    while True:
        S.runCounter()
</code></pre>

<p>The desired behavior is that if <code>self.numbers</code> is being iterated on in the loop, it should finish the loop with the old version before switching to the new version.</p>

<p>Create a lock to control access to your list:</p>

<pre><code>import threading

def __init__(self, ...):
    # We could use Lock, but RLock is somewhat more intuitive in a few ways that might
    # matter when your requirements change or when you need to debug things.
    self.numberLock = threading.RLock()
    ...
</code></pre>

<p>Whenever you need to read the list, hold the lock and save the current list to a local variable. The local variable will not be affected by updates to the instance attribute; use the local variable until you want to check for an updated value:</p>

<pre><code>with self.numberLock:
    numbers = self.numbers
doStuffWith(numbers)
</code></pre>

<p>Whenever you need to update the list, hold the lock and replace the list with a new list, without mutating the old list:</p>

<pre><code>with self.numberLock:
    self.numbers = newNumbers
</code></pre>

<hr>

<p>Incidentally, I've used camelcase here to match your code, but the Python convention is to use <code>lowercase_with_underscores</code> instead of <code>camelCase</code> for variable and function names.</p>

python multithreading